What a Void Undoes
You voided the document. The screen says VOID. And the stock movement report still shows the quantity, or the cashbook still shows the money, or the ledger still shows both legs.
Nearly always, nothing is broken. A void is not a delete and it is not a rewind. It is a second set of postings in the opposite direction, plus a short list of things that get removed outright, plus a shorter list of things that were never designed to come back — and each of those three behaves differently in a report. Knowing which is which is the difference between a five-minute check and an afternoon.
This page is the companion to How work actually runs, which traces one Finalise end to end. This one traces one Void, and the headline is the asymmetry between them: Finalise fans out to thirty-two subscribed processors. Void fans out to ten.
Fifteen minutes, nothing to configure. It applies to every document in the platform, because they are all the same record.
Four different ways to unwind a document, and only one of them is a void
Before anything else, make sure you want a void. The platform has four separate operations here and they take different code paths from the same screen.
| You want to | The operation | What it does | Comes back? |
|---|---|---|---|
| Fix a mistake on something not yet final | Edit the draft | Nothing has posted yet, so nothing has to be undone | n/a |
| Take a finalised document back to editable | Undo to Draft | Returns it to Draft and releases the knock-offs it was holding — and only those; one subscriber, not ten | Yes — you re-finalise it |
| Throw away something that should never have existed | Discard | Marks it discarded and releases its knock-offs and contras | No |
| Cancel a finalised document that really happened, and keep the trail | Void | Posts the reversals below, with a reason, and keeps the document | No |
| Correct a finalised document you are not allowed to void | A credit note, return or refund note | A new document with its own number and its own postings | It is not an undo at all |
A void is the one you want when the document was genuinely raised and genuinely has to be cancelled: a keyed-twice invoice, a cash bill rung up on the wrong till, a payment voucher to the wrong supplier. It keeps the document, its number and its history, and records who voided it and why — the void reason you type is stored on the document, and the whole before-and-after is written to the audit trail in the same call.
A void cannot be undone. There is no un-void. The only route back from a voided document is to key a new one, and it will have a new number.
What actually happens when you press it
Three things happen while you wait, and everything else happens afterwards.
While you wait, BigLedger (1) runs the refusal checks below and stops dead if any of them fires, (2) sets the document’s posting status to VOID and stores your reason, and (3) drops one row into your tenant’s job queue.
That is the whole synchronous part. The reversals have not started.
Then the fan-out. That single queued job is a primary processor, and when a worker picks it up it looks up which secondary processors are subscribed to it and queues one job for each. This is the same publish-subscribe machinery Finalise uses, and the subscription list is the thing worth knowing:
| Subscriber | What it undoes |
|---|---|
| Journal posting | Writes an opposite journal |
| Tax | Reverses the tax transactions behind it |
| Inventory | Writes negating stock movements and replays costing forward |
| Cashbook | Removes the cashbook lines and un-matches the bank statement |
| Knock-off open queue | Gives the source order its outstanding quantity back |
| AR/AP contra | Unpicks the settlements and restores both documents’ balances |
| Membership points | Takes back the points the document awarded |
| Entity spending limit | Releases the customer’s consumed credit |
| Cash transfer | Unwinds the cashbook side of an internal transfer |
| Warehouse pick/pack queue | Removes the document from the picking queue |
Ten. Finalise has thirty-two, and the twenty-two without a void counterpart are not an oversight in every case — several of them could not be undone even in principle. But they are the reason a void can look incomplete when it is finished. The section What a void will not do names the ones that matter.
A void is slower to take effect than a Finalise, and this is measurable
Finalise inserts its queue row and immediately hands the primary processor to a worker thread, so the work usually starts before the HTTP response reaches your browser. The void path only inserts the row. It waits for the next tenant pacemaker tick to be picked up.
So the first thing to do when a report still shows a voided document is nothing at all: refresh in a minute. “Stuck” is the customer’s own word for this, and it almost always means queued.
The three shapes of undo, and why reports disagree about them
This is the part that decides what you see on a screen, and it is not visible anywhere on the screen.
Shape 1 — reversed: a second, opposite entry, and the original stays
The journal. Voiding does not touch the journal that was posted. It reads that journal, swaps every line’s debit and credit, keeps the GL code, branch, profit centre, project, segment and sub-ledger exactly as they were, and posts it as a new journal. The account nets to zero. Both journals are in the ledger, and both are supposed to be — that is what an audit trail is.
So: your account detail will show two entries where you expected none. That is correct. Add them up.
Two things about that reversal are easy to miss.
It carries the original document’s transaction date. Only the posting timestamp is today. Void a January invoice in March and January moves — the reversal lands in January, not in March. If January has been reported, signed off or filed, you have just changed a period you had finished. This is deliberate (an accountant reversing a document wants the reversal where the document was, not smeared into an unrelated month), and it is the single most expensive surprise on this page. Check the document’s date before you void it, not after.
Only one journal is reversed. The reversal reads a journal for the document and reverses that one. A document that produced more than one journal header — and a foreign-currency document with a separate gain/loss posting is the obvious case — will not have the others reversed by this path. If your account is left with one leg standing after a void, this is the first thing to check, and it is the mechanism behind the desk’s “void reversal journal unbalanced” reports.
Tax follows the same shape, with one condition: the tax reversal runs only if the document’s journal posted. Tax follows the journal, not the document. A document that finalised but never produced a journal has nothing for the tax reversal to do, and it will quietly do nothing.
Shape 2 — negated: an opposite movement, and the original stays
Inventory. The void rebuilds the document’s stock movements, negates each quantity, stamps each
one with the transaction code VOID, and inserts them as new rows in the stock ledger. The
original movements stay exactly where they were.
This is the answer to the loudest symptom in the whole void family — “voided stock adjustment still showing in stock movement report”. A movement report shows movements, and a void makes a movement. Both rows are real, both are supposed to be there, and the two net to zero. Your stock balance is right; your stock movement report has two lines where you expected none. Check the balance, not the movement list.
Then, per negating line, three more jobs are queued:
- costing is replayed forward from the movement immediately before the one being undone, so every later line’s moving average is recomputed — which is why a margin you looked at yesterday can move today;
- brought-forward and carried-forward balances are recalculated for the periods after it;
- the current stock balance is refreshed, including serial numbers, bins and batches.
And the document’s serial numbers are unlocked — released back to available. That is usually what you wanted, and it is worth knowing it happens, because it is also how a serial that “should have been sold” becomes sellable again.
One condition governs all of it: the negation only happens if the document actually posted to inventory. A document whose inventory posting never ran has nothing to negate, and the void will mark it voided without writing a single stock row. That is the “posting_inventory null after void stock adjustment” shape, and the check below will show it to you.
Shape 3 — removed: the row is taken away, not reversed
Four things are deleted rather than reversed, and this is why the cashbook and the AR/AP screens behave differently from the ledger after a void.
Cashbook lines are removed, not reversed. No opposite cashbook entry is written; the lines are marked deleted. And the removal is careful about the bank reconciliation: in one transaction it adds each matched amount back onto the bank statement line’s open amount, deletes the reconciliation links, and then removes the cashbook line.
Read that consequence slowly, because it reaches into a month you may have closed: voiding a document that was already reconciled puts its bank statement line back on your unmatched list. The reconciliation you signed off is now one line short of balanced. That is the design working — the alternative is a reconciliation matched to a transaction that no longer exists — but nobody tells you it happened.
Note also what the stored reconciliation header does not do: it does not re-derive itself. See Everything is matched to zero and the reconciliation still won’t tally.
Settlements (contras) are removed, and both sides are recalculated. Every contra the voided document takes part in is deleted, and then the outstanding balance is recomputed for both documents in each one. Void a receipt voucher and the invoices it paid go back to outstanding — that is the intended behaviour and it happens inside the same job, not on a schedule.
Knock-off queue rows are removed, which is how a sales order gets its outstanding quantity back when the invoice raised from it is voided.
Aging snapshots are removed — all of them. The monthly aging snapshot rows for that document are deleted permanently, with no date limit. So a voided invoice disappears from last month’s aging report and every earlier one, not just this month’s. If you print aging reports for the auditor, print them before you void, because the void rewrites the history.
What a void will not do
Seven limits. Each of these is a thing a reader has assumed and been wrong about.
- It will not recall an e-invoice that has already gone to LHDN. The void removes the document from the submission queue only while the submission has not happened. Once it has been submitted, the queue row and the submission record both stay, and nothing about a void reaches LHDN. The correction there is a cancellation request inside 72 hours or a credit note after — see Cancelling and correcting a validated e-invoice. In practice you will usually not get this far, because the refusal in the next section stops you first.
- It will not give the document number back. A voided document keeps its number permanently; nothing returns a number once it has been written onto a document. See Document numbering, which has the counter and the one exception (a save that is rolled back before the number is written).
- It will not remove the original journal from the ledger, or the original movement from a stock movement report. Both shapes above leave the original standing on purpose.
- It will not reverse a foreign-currency document’s journal. The reversal path refuses a forex document outright. If you void one, the rest of the void proceeds and the journal reversal does not happen — and nothing on the screen says so.
- It will not reverse a journal that was never posted. A document that is FINAL with no journal behind it has nothing to reverse, and the reversal job fails rather than doing nothing visible. (The document is Final but it is not in the general ledger is the same problem seen from the other end.)
- It will not tell you when one of its jobs fails. The void’s ten jobs run after your screen has come back. A failed one writes a row to an error table and raises nothing you will ever see. This is the general condition described in How work actually runs, and it is why the check below exists.
- It will not be undone. There is no un-void, on any document type.
And one we could not establish, stated as such. Several things Finalise starts have no void counterpart in the processor registry — sales commission, budget commitments, finance charges, intercompany mirror documents, coupons, and webstore or marketplace status updates among them. We have confirmed the absence of a registered void subscriber for each; we have not confirmed what that means for your data in every case, because some of them are reversed elsewhere (the aging snapshot and the e-invoice queue both are, inline, without a subscriber), some are genuinely irreversible (an order confirmation e-mail cannot be unsent), and some may simply be left standing. If you rely on commission, budgets or intercompany postings, check them by hand after a void and tell us what you find.
When BigLedger refuses to void at all
Four refusals, all checked before anything is written, so a refused void changes nothing.
The document has been used downstream. If any other document has been raised from this one — an invoice from this order, a payment against this invoice — the void is refused and the message lists the blocking documents by type and number. That list is the instruction: void them first, in reverse order, working back from the last document to this one. This is the commonest refusal and the most useful one, because the error tells you exactly what to do.
Only a final document can be voided. A draft is discarded or deleted, never voided. If the button does nothing, check the posting status first.
A sales order that is already being picked. An order whose warehouse picking list is at pending picking is refused, because stock is being physically pulled against it. Cancel the pick first. (The error code on this branch says something about e-invoice, which is a mislabelling on our side — read the message, not the code.)
E-invoice is enabled for the company. This is the big one, and it surprises everybody who turns e-invoicing on. Once a company’s e-invoice status is ENABLED:
- sales invoices, sales returns, credit notes, debit notes and refund notes cannot be voided at all — the correction is a credit note or a cancellation request, not a void;
- a cash bill can be voided, but only until its e-invoice has been submitted. After submission, refused;
- a self-billed purchase document cannot be voided.
This is not a bug and it is not a permission you can be granted. It is the platform refusing to let you silently cancel a document that a tax authority has a copy of. If you enabled e-invoicing last month and “void stopped working”, this is why — and it is the “before this I could” shape that turns up across the whole corpus.
What success looks like: the thirty-second check
A document does not have one posting status. It has one per subsystem — journal, inventory, cashbook, tax, membership and a dozen more besides — and they move independently. That is precisely what makes a half-finished void diagnosable.
Open the voided document and go to its Posting tab. You are looking at journal, inventory, cashbook, membership and tax status side by side.
On a void that finished, every subsystem the document used reads VOID.
Read it like this:
| What you see | What it means |
|---|---|
All relevant statuses VOID | The void completed. Any leftover you see in a report is one of the “original stays” shapes above — go add up the two rows. |
Some VOID, some still POSTED | The void partly ran. One of the ten jobs failed. This is real and it is what you came here to find. |
| A status blank | That subsystem never posted in the first place, so the void had nothing to undo there. Not a void failure — a Finalise one. |
FAILED | Rare. Nothing on the void path sets it; treat it as a partial run. |
Then, if it is a partial run, open Trace Document in the Financial Report applet, which reports why a given document did or did not produce a journal. And raise it — a stuck void does not re-drive itself.
Two more checks worth thirty seconds each, in the cases where they apply:
- Voided a receipt or payment? Open the invoices it was knocking off. Their outstanding balance should be back. If it is not, the contra reversal is the job that did not run.
- Voided something that was bank-reconciled? Open that reconciliation. The statement line should be back on the unmatched list. It being there is correct; it being absent means the cashbook removal did not run.
Common mistakes
Voiding a prior-period document without looking at the date. The reversal lands in the original period. Look at the document date first; if the period is closed or reported, a corrective document in the current period is usually what you actually wanted.
Reading a movement report as a balance. A void adds movements. Two rows netting to zero is a completed void, not a phantom one. Check the stock balance.
Voiding the invoice before the payment. The refusal will stop you, but people then void the payment, re-try, and lose track of what they have unwound. Work backwards from the newest document and write the list down first.
Assuming the void reached LHDN. It did not, and after submission the platform will not even let you try. Use the cancellation path.
Treating “still showing” as “failed” within the first minute. The void queues its work and waits for the next tick. Refresh before you investigate.
Printing the aging report after the void. The snapshots are gone by then — for every month, not just this one.
Related documentation
- How work actually runs — the same machinery seen from the Finalise side: the queue, the fan-out, what the cron sweeper catches and what it does not.
- The generic document — why one explanation of void covers every document type in the platform.
- When two numbers don’t tally — the stored-against-live trade-off that a void interacts with everywhere: the aging snapshot, the reconciliation header, the order’s outstanding quantity and the cost on a line.
- Cancelling and correcting a validated e-invoice — what to do instead, once a document has reached LHDN.
- Journal entries — voiding and re-posting a manual journal, which follows the same reverse-rather-than-edit rule.
- Financial Report applet — Trace Document and the other Error Checking screens.