dimhold.by
← Writing

Benford's law flags 84% of the 2025 annual reports. A perfectly honest source would get 60%

Benford’s law is the fraud screen everybody near finance software has heard of. In real numbers the first digit is 1 about 30% of the time and 9 less than 5%. People who invent numbers do not reproduce that, so the histogram is supposed to point at the liar.

In 2013 I ran it on the git history of express, where nobody has a reason to fake anything. Of 4 columns, 3 failed. I blamed the data, those columns span too few orders of magnitude. Dollar amounts in an annual report span many, so there the screen should be at home. I also noted that MAD never asks how many rows produced it and left open how much faking it takes to be noticed. I never went back to either question.

So I took every annual report filed with the SEC in 2025 and ran it.

The setup

The SEC publishes the XBRL numbers of all filings as quarterly archives, the Financial Statement Data Sets. On 8 October 2026 I took every 10-K filed in 2025, without amendments: 5530 reports. From each one I kept the values in US dollars, without segment breakdowns, at least 10 in absolute value and with exact repeats of a tag in the same period dropped. Reports with fewer than 50 such numbers were dropped, 5399 stayed.

The score is the one from Mark Nigrini’s book: the mean absolute deviation (MAD) of the 9 first digit shares from Benford. His thresholds for the first digit are 0.006, 0.012 and 0.015. Above 0.015 a set of numbers “does not conform”. The counting is Python 3.12 with numpy 2.5.

This is not a new idea. Klaus Henselmann and coauthors ran it on S&P 500 XBRL filings for 2010. In 2015 Dan Amiram and coauthors found their first digit score higher before SEC enforcement actions. In 2022 Stephen Walker answered that it predicts misstatements worse than the F-score or plain sales growth. I wanted to see it on fresh data.

1 million numbers and 5399 reports

All 1 116 430 numbers together are almost a textbook. The digit 1 starts 30.35% of them, Benford says 30.10%. The MAD of the whole pile is 0.00074.

Scored one by one, 2 reports were “close conformity”, 289 “acceptable”, 580 “marginal” and 4528 “nonconforming”. That is 83.9% of the 5399 reports.

My first reaction was that the market is full of fiction, which is obviously wrong. The second was that the median report has only 210 numbers. If you draw 210 digits from a perfect Benford source, the shares will wobble and MAD measures exactly the wobble. I simulated it, 4000 draws for every report size.

MAD of a perfect Benford source by the size of the sample 0.00 0.02 0.04 0.06 0.015: Nigrini's "nonconforming" 210 numbers: 0.0158 median up to 99th percentile 2025 10-K reports by size 50 200 400 600 800 1000 numbers in the report
4000 simulated draws from Benford for every size in steps of 10. Report size is the count of dollar values per 10-K after the filters in the text.

A perfect source with 210 numbers has a median MAD of 0.0158, already above the line. It goes below 0.015 only at about 240 numbers. If every report were drawn from an honest generator, Nigrini’s rule would still call 60.3% of them nonconforming. Most of the 83.9% comes from the size of the report.

Before counting I wrote down what would prove me wrong. If small reports were flagged less than twice as often as large ones, size is not the reason. They are flagged 97.5% against 68.0%, which is 1.43 times, so by my own rule this part failed. The rule was badly written, a share near 100% cannot double and the honest source shows the same slope from 88.9% to 32.8%. But I wrote it before the number and the number did not pass.

share flagged "nonconforming" (MAD > 0.015), by report size real 10-K reports perfect Benford, same sizes 0% 50% 100% 97.5% 88.9% 50–146 numbers n = 1334 87.8% 68.5% 146–210 numbers n = 1357 82.3% 51.4% 210–256 numbers n = 1351 68.0% 32.8% 256–954 numbers n = 1357
Quarters of 5399 reports by count of numbers. The honest bars are the mean probability that a perfect Benford sample of the same size goes above 0.015.

Correcting for size

The fair question is how unusual a MAD is for its size. For each report I took the percentile of its MAD among simulated honest ones of the same size. Above the 99th percentile there should be 1% of reports. There are 15.9%.

My guess was that a report repeats itself, the same amount under several tags or as an unchanged balance in 2 years. When I counted every distinct value only once the share fell to 8.2%, over 5250 reports with enough distinct values. The rest is still 8 times more than chance and I can not say what it is. Totals are sums of the lines above them, so a report is not a set of independent draws, but I did not go deeper.

Does any of this point at a problem

A screen is useful only if the flagged reports are worse. I needed an outcome I could count. The first idea was the prevrpt field, “this submission was later amended”. It is 0 in all 5530 rows, so in these archives nobody fills it in after the fact.

The first outcome that worked: the next 10-K, filed in 2026, repeats last year’s net income and equity. If either moved by more than 1%, something changed. For 4473 reports I had both filings. In 153 of them the old number moved. The area under the ROC curve (AUC) of the raw MAD was 0.53, with a 95% bootstrap interval from 0.49 to 0.58. Corrected for size it was 0.50, a coin. Report size alone gave 0.58: reports with fewer numbers had their old numbers changed more often and they also have higher MAD.

That outcome is dirty, it mixes error fixes with reverse mergers. So after seeing it I added a second one, chosen after the first result and not before. Since 2023 the cover page of a 10-K for listed companies has a checkbox: the statements reflect the correction of an error in previously issued statements. I downloaded the cover of the next 10-K for 4576 reports. 4520 have the box and 127 of them have it checked.

Among reports Nigrini’s rule calls nonconforming, 2.64% later corrected an error. Among the rest, 3.63%. That gap alone could be chance, but the AUC of the raw MAD is 0.41 with an interval from 0.37 to 0.46, so the raw screen points the wrong way. Companies that tick the box have bigger reports, median 240 numbers against 212. Bigger reports get flagged less. I think that is the whole story, but I did not run a regression to prove it. Corrected for size the AUC is 0.47 and the interval from 0.42 to 0.53 includes the coin.

later corrected an error, by Nigrini's verdict 0% 2% 4% 2.64% nonconforming n = 3749 3.63% the rest n = 771 invented numbers mixed in vs reports caught 0% 0% 50% 50% 100% 100% 5.3% 21.8% 60.3% 92.1% share of numbers replaced
Left: 4520 reports whose next 10-K cover has the error correction checkbox. Right: the threshold is the top 5% of the same reports without invented numbers, so 0% replaced is caught 5% of the time by construction.

How much fiction it takes

The last check went the other way. I took the real reports and replaced a share of their numbers with invented ones. In those every first digit from 1 to 9 is equally likely. The screen flags the top 5% by size corrected score. At the first try the threshold came out as 1.0 and nothing was ever caught. The percentile saturates when a report is beyond all 4000 simulations. I almost wrote that down as a result. With a z score instead, replacing 30% of the numbers was caught in 5.3% of reports, the same as with no fiction at all. Half the numbers made up gave 21.8%. It takes 70% of invented numbers to catch 60.3% of reports.

Uniform digits are a crude model of a liar. My guess is that a real misstatement touches a few lines, like revenue or one reserve. A few numbers get lost among 210 even more easily.

What I did not check

I did not match against SEC enforcement releases, the outcome where Amiram and coauthors found their signal. I used one year without any controls, so this does not refute their paper. The second and the last digits I did not count. I do not name any company, a Benford flag is not an accusation and after this run I am not sure it is even a hint.

In my data first digits raise the alarm mostly in small reports. The pile of all reports together still matches the law to 0.00074. As a screen for a single annual report I will not use it without a size correction. Even with it I have nothing that shows it finds errors.