The difference is evidence, not noise
When a reconciliation does not balance, the usual response is to start at the top and read down, comparing rows until something looks wrong. On a two-hundred-row account that is an afternoon, and it fails often, because the eye stops seeing after about forty lines.
There is a much better first move, and it takes a calculator. The size of the difference is not arbitrary — it is produced by whatever went wrong, and different failures produce differences with different mathematical properties. A missing row produces a difference equal to that row. A sign error produces double. A swapped pair of digits produces a multiple of nine, always, without exception.
So before reading a single transaction, interrogate the number itself. Four divisions and one search will identify the cause in the large majority of cases, and will tell you which rows to look at rather than sending you through all of them. This article walks through each fingerprint, why the arithmetic works, and the order to test in.
One assumption up front
The order to test in
Run the cheap, decisive tests first. Each one either identifies the cause or eliminates an entire family of causes, and none of them requires reading the ledger line by line.
One: is the difference the same as last period? Two: does it equal an amount on the statement exactly? Three: is half of it an amount you recognise? Four: is it divisible by nine? Five: does it equal the sum of several consecutive rows?
That sequence is not arbitrary either. Test one tells you the problem is not in this period at all, which saves you from searching a month that contains nothing wrong. Tests two through four each cost a single operation. Test five is the most work, so it goes last.
The same number every month: the opening balance
If the difference is identical this month and last month — not similar, identical — then nothing in either month caused it. A recurring, unchanging difference is a fixed offset, and a fixed offset comes from the point where the account began.
The two usual origins are a wrong opening balance when the account was first set up in the ledger, and an adjustment posted directly against the balance without a corresponding transaction. Both create a permanent gap that every subsequent period inherits, and neither will ever be found by examining this month's activity.
This one is worth checking first precisely because it is invisible to every other technique. People search for it for months. The correct fix is at the source: correct the opening balance, or post the missing entry with a proper date and explanation. Posting a plug every period to make the current month balance simply guarantees the same work forever.
The tell you will miss
Equal to one amount: a row missing or a row twice
If the difference matches a single transaction on the statement exactly, that transaction is the story. There are only two possibilities, and a search of the ledger distinguishes them immediately.
No match in the ledger means the row was never entered. Two matches means it was entered twice. The second case has become far more common than it used to be, because it is what a re-run import produces: a load fails halfway, someone runs it again, and the first half now exists in duplicate.
Duplicates are worth a moment of respect. They are the failure most likely to survive review, because every individual row in a duplicated pair looks perfectly legitimate — correct date, correct amount, correct description. Nothing about either row is wrong. Only their coexistence is. That is why deduplication has to be a deliberate check rather than something you hope a reader notices.
Exactly twice an amount: a sign on the wrong side
Halve the difference. If the result is an amount you recognise from the statement, you have found a classification of direction — a receipt recorded as a payment, a credit recorded as a debit, money in booked as money out.
The doubling is not a coincidence, and understanding why makes the test memorable. A receipt of 2,400 entered as a payment is wrong twice: the 2,400 that should have increased the balance is absent, and a 2,400 that should not exist is decreasing it. The gap between where the balance is and where it should be is therefore 4,800 — two times the amount, never one.
This makes sign errors unusually easy to find once you know the trick, and it is one of the more common failures in practice because it survives casual review so well. The amount is right. The date is right. The description is right. Only the direction is wrong, and direction is the one attribute the eye does not naturally audit.
The same error in extraction
Divisible by nine: a transposition or a slipped decimal
This is the oldest trick in bookkeeping and still the most useful. If the difference divides evenly by nine, you are almost certainly looking at two digits that swapped places, or a decimal point that moved one position.
The reason is straightforward. Swapping two digits changes a number by the difference between those digits multiplied by the difference between their place values — and the gap between any two powers of ten (90, 900, 9,900) is always a multiple of nine. Write 5,841 where you meant 5,481 and you are out by 360, which is 9 × 40. It cannot come out any other way.
A slipped decimal behaves the same way for the same underlying reason. Record 123.45 where the true figure was 1,234.50 and you are short by 1,111.05 — nine tenths of the original, and therefore divisible by nine as well.
To tell the two apart, divide the difference by 0.9. If the answer is an amount that actually appears on the statement, it is a decimal shift and you have just identified the exact row. If it is not, divide by nine instead: the result is the digit gap times the place value, which tells you roughly how large the affected number is and narrows the candidates to a handful.
| What you see | The arithmetic | What it means |
|---|---|---|
| Difference 360 | 360 ÷ 9 = 40 | Two digits swapped, gap of 4 in the tens/hundreds range |
| Difference 1,111.05 | ÷ 0.9 = 1,234.50 | Decimal moved one place on a 1,234.50 row |
| Difference 9 | ÷ 9 = 1 | Adjacent digits differing by one — the smallest possible transposition |
| Difference 4,500 | ÷ 9 = 500 | Larger place values involved; look at four-figure amounts |
A run of consecutive rows: the page boundary
If none of the single-row tests fits, the difference may be the sum of several rows rather than one. Adding consecutive transactions and comparing running subtotals to the difference sounds tedious, but you do not need to try every combination — consecutive losses are not random, and they cluster in one place.
They cluster at page boundaries. The last rows of a page and the first rows of the next are the ones that go missing when a document is read imperfectly, when a copy-and-paste captures only what was visible, or when a header repeated at the top of each page is mistaken for the start of the data.
So look at the page breaks first. Count the rows on each page of the original and compare with what arrived. A page that lost its first three rows is far more common than three unrelated rows going missing from three unrelated places, and it is much faster to confirm.
This is also the failure that most deserves an automated check rather than human attention, because there is nothing about the surviving data that looks wrong. We wrote about how we hunted this class of loss in our own extraction in eliminating row loss in PDF extraction.
The fingerprint table
The whole diagnostic on one page. Work down it in order; each row is a single operation.
| Property of the difference | Most likely cause | How to confirm |
|---|---|---|
| Identical to last period | Wrong opening balance or a direct balance adjustment | Compare three periods; if unchanged, go to setup |
| Grows by the same amount each period | A recurring item never entered | Look for a fee, standing order or subscription |
| Equals one transaction exactly | That row is missing or duplicated | Search the ledger for the amount: nil hits or two |
| Exactly twice a transaction | Amount on the wrong side | Halve it, find that amount, check its direction |
| Divisible by nine | Transposed digits or a slipped decimal | Divide by 0.9; if that amount exists, decimal shift |
| Equals a sum of consecutive rows | Rows lost at a page boundary | Count rows per page against the original |
| Small and irregular | Rounding or currency conversion | Verify against the rate used, then post deliberately |
| Fits nothing above | Two errors cancelling, or a genuine bank error | Reconcile in halves to isolate; then query the bank |
Two checks, two different blind spots
Before any of this helps, the statement itself has to be complete. There are two independent ways to test that, and the important point is that neither one covers for the other.
The balance chain.Most statements print a running balance on each row. Take any row's balance, subtract the previous row's, and the result should equal that row's amount. Run it down the whole statement and a single misread number lights up immediately, on the exact row.
Its blind spot is severe: if a row vanishes entirely, the chain closes over the gap. The row before and the row after still agree with each other perfectly, because the arithmetic no longer knows anything is meant to sit between them. A statement can pass the chain check while missing a dozen transactions.
The totals identity. Opening balance plus the sum of every transaction should equal the printed closing balance. This one catches exactly what the chain misses, because a dropped row leaves the sum short. It is a statement about the document as a whole rather than about any row.
Its own blind spot is compensating errors: two mistakes of equal size in opposite directions leave the total untouched. So run both. Together they are strong; individually each has a hole large enough to lose a month through.
| Check | Catches | Blind to | Needs |
|---|---|---|---|
| Balance chain (row to row) | A misread amount on a row that carries a balance | Rows dropped entirely — the chain just closes up | A printed running balance column |
| Totals identity (opening + Σ = closing) | Dropped rows, missing pages, short imports | Two errors that cancel each other out | Printed opening and closing balances |
| Both together | Nearly every mechanical failure | Correct amounts posted to the wrong category | A single-account statement |
When the identity cannot be run at all
Some documents will not support the totals check, and knowing which ones matters more than it sounds. The commonest case is a statement covering several accounts under a single header — a current account, a savings account and a card, each with its own running balance, all printed in one document with one opening and one closing figure at the top.
One opening and closing pair cannot span several chains. Summing every transaction in the document and comparing to that pair produces a number with no meaning, and the honest answer is that the identity could not be evaluated — not a green tick.
We take that seriously in our own product: when a document has more than one account, the totals check stands down and says so, rather than displaying a confirmation it cannot support. A check that reports success when it did not actually run is worse than no check, because it converts uncertainty into false confidence.
The practical response is to split the document by account and run the identity on each chain separately. That usually restores the check completely, and it is also what you need for the ledger anyway.
We will not promise you 99 % — we will show you which rows to check
Every converter in this market advertises a number: 99 %, 99.5 %, 99.8 %. None of them publishes how it was measured or on which documents — and none of them can tell you which rows fall in the remainder. That is the part you find out later, when two amounts have been glued into one, a column has slid one place to the left, and a reconciliation will not close.
Our extraction is strong. It is also not magic — and neither is anyone else’s.
Reading a PDF is not a solved problem. A layout nobody has seen before, a faded thermal receipt, a bank that marks credits in its own way — each of those can produce a row that looks perfectly ordinary and is wrong. We build hard against that, and we still refuse to sell you a number, because the number is not the thing that protects you. Knowing exactly where to look is.
What actually goes wrong when a PDF is read
These are not hypotheticals. Every one of them is a defect we have found in real documents, reproduced, and built a check for — which is precisely why we can now point at them instead of averaging them into a percentage.
| The defect | What you see in the export | What it costs |
|---|---|---|
| Two amounts glued into one | One plausible-looking figure instead of two rows | A total that is short by a whole transaction |
| A column slides one place | Dates in the description, amounts in the balance | Every row after it is wrong, and none looks wrong |
| A reference number read as the amount | “Payment 910015” booked as 831.00 | A five-figure hole on a long statement |
| A credit sign dropped | An expense recorded as income | The error is twice the amount, in the wrong direction |
| A summary box counted as bookings | “Previous balance / New balance” added as rows | Totals inflated by exactly the closing balance, twice |
| A page silently skipped | A month that is simply shorter | Nothing to see — that is what makes it the worst one |
So we built the layer that catches them
A second engine, deterministic — ours, and it runs on every document
After the AI reads the document, a separate layer re-does the document’s own arithmetic. Opening balance plus every transaction must equal the closing balance the bank printed. Each row’s running balance must follow from the one above it. Line items must sum to the invoice total. No AI, no confidence score, no guessing — these are proofs, and a document that fails one is provably misread.
It names the rows, not a percentage
When a check fails you do not get a lower score. You get row 48, row 133, row 1 902 — highlighted in place, red where a check proved the reading wrong and amber where it could not confirm it, with the column the check named brighter still. Open the Rows or JSON view, fix those, export. That is the whole loop, and it usually takes under a minute.
The document is the judge, not us
A bank statement carries its own proof: it can catch an error with no human, no reference data and no opinion from us. That is why we lead with it. Where a document genuinely cannot check itself — no running balance, no printed total — we say so, plainly, instead of letting silence imply that everything is fine.
Why the percentage is the wrong number to buy on
| Statement size | What “99 % accurate” quietly allows | What that means for you |
|---|---|---|
| 300 rows | 3 wrong rows | An afternoon — if you find them |
| 1 200 rows | 12 wrong rows | A reconciliation that will not close |
| 3 400 rows | 34 wrong rows | A six-figure error, in cases we have seen |
Money work rewards being picky
Please read the flagged rows before you export. That is not a disclaimer — it is the one step that turns a good extraction into a correct one, and we have spent our engineering effort on making it short and precisely targeted rather than on rounding a number up. Anyone can print 99 %. Telling you exactly where the other 1 % is, is the harder promise, and it is the one we are willing to make.
Genuine reconciling items are not failures
A share of every difference is not an error at all, and treating legitimate timing items as mistakes wastes a great deal of time. A cheque written on the 30th and presented on the 3rd is correctly in your books and correctly absent from the statement. Both records are right; they describe different moments.
The same applies to deposits in transit, card payments authorised but not yet settled, and transfers that cross a period end. These get listed as reconciling items, carried forward, and cleared next period when they land. They are not corrected, because there is nothing to correct.
The discipline that matters is aging them. A timing item that is still outstanding two periods later has stopped being a timing item and has become something else — a cheque that was never presented, a transfer that failed silently, or an entry that should never have existed. Any reconciling item older than about sixty days deserves an explanation rather than another carry-forward.
When nothing fits: compensating errors
Occasionally the difference matches none of the fingerprints. Usually that means there is more than one error, and their interaction has produced a number that reflects neither of them cleanly.
The technique here is bisection, and it is far more efficient than reading. Reconcile the first half of the period on its own. If that half balances, both errors are in the second half; if it does not, you now have a smaller difference to fingerprint, which often becomes recognisable once it is separated from the other one. Repeat. Each cut halves the search space, so even a three-hundred-row month resolves in about eight steps.
The worst version is two errors of identical size on opposite sides, which cancel completely and leave no difference at all. That is not a reconciliation failure — it is a reconciliation that passes while being wrong, and no amount of balancing will surface it. It is caught by review of the individual entries, or not at all, which is the subject of what "reconciled" actually proves.
A worked example
A month closes with the ledger 4,806.00 below the bank. Rather than reading two hundred rows, run the tests.
Last month reconciled cleanly, so it is not an opening-balance offset. No transaction equals 4,806.00, so it is not one missing row. Halving gives 2,403.00 — no such transaction either. Dividing by nine gives 534.00, which is not obviously useful. Dividing by 0.9 gives 5,340.00, which is not on the statement.
Nothing fits, which itself is information: suspect two errors. Bisect. The first fortnight reconciles to a difference of 4,800.00 — and half of that is 2,400.00, which is a customer receipt sitting in the ledger as a payment. One sign error, found.
That leaves 6.00 in the second fortnight, which divides by nine to give 0.67 — not clean. But it also equals 6.00 exactly, and a search finds a bank fee of 6.00 never entered. Two causes, both identified, without reading a single row that was not implicated.
| Step | Test | Result |
|---|---|---|
| 1 | Same as last period? | No — last month reconciled |
| 2 | Equals a transaction? | No match for 4,806.00 |
| 3 | Halve it: 2,403.00 | No match — suspect more than one error |
| 4 | Bisect: first fortnight | Difference of 4,800.00 |
| 5 | Halve it: 2,400.00 | Receipt booked as a payment — found |
| 6 | Remainder: 6.00 | Unentered bank fee — found |
Preventing the recurrence
Finding the difference is the immediate job. Not finding it again next month is the valuable one, and it costs almost nothing: write down which of the six causes it was, in one line, every time.
After three or four months the log stops being a record and becomes a diagnosis of your process. Transpositions clustering in one account means somebody is typing where they should be importing. Duplicates recurring means an import has no idempotency and someone re-runs it after failures. A constant difference means a setup problem nobody ever went back to.
Each of those has a fix at the process level that costs one afternoon and removes the failure permanently. Without the log you keep solving instances of a problem you have not identified — which is, in practice, why the same difference is found twelve times a year in a great many organisations.
| Recurring cause | What it says about the process | The fix |
|---|---|---|
| Transpositions | Amounts are being typed by hand | Import instead of key; keying is where digits swap |
| Duplicates | An import can be run twice with no protection | Deduplicate on a stable transaction identifier |
| Missing rows in blocks | A document is being read or pasted incompletely | Run the totals identity before reconciling |
| Sign errors | Credit and debit columns are ambiguous somewhere | Fix the column mapping, not the individual entries |
| Constant difference | Setup was never corrected | Repair the opening balance at source, once |
| Late timing items | Reconciling items are not being aged | Review anything outstanding beyond sixty days |
At volume, the economics change
Every technique here gets more valuable as the row count rises, because reading does not scale and arithmetic does. Searching two hundred rows by eye is unpleasant; searching two thousand is not realistic, and a firm handling many clients is working at the second scale routinely.
Two habits do most of the work. First, run the completeness identity on every statement at the point of conversion, before it reaches anyone's ledger — that removes the entire class of "the data was wrong before I started". Second, reconcile more often on high-volume accounts. The cost of a search grows with the candidate set, so weekly reconciliation on a busy account is genuinely cheaper in total time than monthly, even though it happens four times as often.
For the mechanics of handling a large estate of statements, we covered the workflow separately in processing bank statements at scale and in consolidating a year of statements.
Common mistakes when hunting a difference
Reading before calculating. The single most expensive habit. Four divisions take a minute and usually name the cause; reading two hundred rows takes an afternoon and often does not.
Posting a plug. An adjustment that makes the difference disappear without explaining it does not close the issue — it hides it, and it hides every future difference inside the same account. If a small amount genuinely cannot be found, write it off deliberately, with a reason and a date.
Carrying it forward. A difference that survives one period becomes invisible by the third. People stop looking at a number they have seen before, and the next problem then hides inside it.
Assuming the bank is right. Usually it is, but not always. Duplicated charges and fees applied twice do happen, and reconciliation exists precisely to catch them. If every internal cause is genuinely eliminated, the statement is a legitimate suspect.
Fixing the entry and not the cause.Correcting today's transposition without asking why an amount was being typed guarantees you will correct another one next month.
Key takeaways
A difference is evidence with a measurable shape, and interrogating the number beats reading the ledger almost every time. The same amount every period means the opening balance. Equal to a transaction means missing or duplicated. Twice a transaction means a sign on the wrong side. Divisible by nine means digits swapped or a decimal moved.
Establish that the statement is complete before you reconcile against it, using both the balance chain and the totals identity — their blind spots are in different places, so neither substitutes for the other. And when a document covers several accounts, accept that the identity cannot run rather than accepting a tick that means nothing.
Finally, log the cause every month. The list of causes is short and repetitive, and after a few months it stops describing incidents and starts describing your process — at which point the fix moves from finding differences to not producing them.
Frequently asked questions
Start from a statement you know is complete
Every statement we convert is checked against its own arithmetic: opening balance plus every transaction against the printed closing balance. If it does not hold, you get the gap and the rows worth examining — before any of it reaches your ledger.
