Cloudflare's Turnstile error docs invented 20 codes, then deleted them
If you searched a Cloudflare Turnstile error code between December 2025 and March 2026, there is a fair chance the page you found is wrong — and still wrong today, because nobody went back to fix it. The reason this is checkable rather than a suspicion is that cloudflare/cloudflare-docs is a public repository, so the documentation has a diffable history and you can fetch any file at any commit.
How to check a vendor's documentation against itself
The technique generalises, which is most of why this is worth writing down. Cloudflare publishes its documentation as a repository, so every claim in it has a timestamp and a diff. One curl per revision:
# The default branch is `production`, not `main` — this catches people.
curl -s "https://raw.githubusercontent.com/cloudflare/cloudflare-docs/<sha>/\
src/content/docs/turnstile/troubleshooting/client-side-errors/error-codes.mdx"Fetching that file at six revisions and counting the documented numeric codes produces this:
| Date | PR | Numeric codes |
|---|---|---|
| 2025-06-02 | #22827 | 13 |
| 2025-10-03 | #25600 | 14 |
| 2025-12-19 | #27237 | 33 |
| 2026-01-29 | #27880 | 33 |
| 2026-03-06 | #28831 | 9 |
| current | — | 9 |
Thirteen, then thirty-three, then nine. Something large went in and came back out, and the window between those two revisions is seventy-seven days.
Twenty codes that existed for 77 days
The 100010, 102010, 103010, 104010, 105010, 106010 and 120010 families appear in the 19 December revision and in no revision before or after it. They are enumerable — you can list them — and they were documented for about eleven weeks.
Anyone who wrote about Turnstile error codes in that window, in good faith, working from the official documentation, published codes that do not exist. Those pages are still up. There was no announcement when the codes were removed, because removing something from documentation does not generate one.
Seven codes that were redefined, then deleted
This is the worse category, because a wrong definition is more dangerous than a missing one — a missing code sends you looking, a wrong one sends you somewhere.
| Code | Before | December 2025 | Today |
|---|---|---|---|
110420 | Invalid action | Rate limiting active | gone |
110430 | Invalid cData | Account suspended | gone |
Consider what the second row does to someone debugging. You hit 110430 in January, read the documentation, and conclude your Cloudflare account has been suspended. That is a completely different afternoon from "the cData attribute on your widget is malformed". You would have reasoned correctly from a definition that was wrong.
110500, 110510, 200010, 400030 and 400040 moved the same way — redefined in December, absent by March.
`400020`, followed all the way through
This one is worth tracing in full, because two separate parties did careful work on top of a wrong definition and the process made it worse rather than better.
400020had been Invalid sitekey.- The December revision changed it to Invalid widget size.
- Someone filed an issue against that definition — reasonably, because it was in the documentation and it did not match what the widget emitted.
- A pull request was merged on 29 January adding
flexibleto the list of valid sizes. That is a careful fix to the wrong problem: it deepened the incorrect definition rather than removing it. - In March, the whole thing reverted to Invalid sitekey.
So for roughly two and a half months, the published meaning of 400020 disagreed with the widget's behaviour, a bug report was filed about the mismatch, and the correction reinforced the error. Nobody involved did anything unreasonable at any step.
What the current table does not say
The live table lists nine numeric codes plus two wildcard families, 300* and 600*, with a note that "the remaining digits… are for internal use". Which means the two codes people search for most — 300030 and 600010 — are not individually documented at all. 600010 has only ever appeared as a parenthetical; 300030 appears nowhere.
That is not an oversight so much as a decision about what a wildcard is for, but the practical effect is that the two most-searched Turnstile errors have no official definition to look up. We document them at error 300030 and error 600010, which is a slightly uncomfortable position to be in and an honest one.
Three codes are also *new* since March — 110600, 110620 and 400070 — and appear on almost no third-party page, because the third-party pages were written earlier. The error index carries all of it with dates.
The part we got wrong
An article about someone else's documentation being wrong owes an account of its own near miss.
Our own research notes recorded that two string codes, invalid-widget-id and invalid-parsed-secret, had been documented in 2024, removed, and were still being emitted by siteverify. It was a good detail and it fit the argument. Going looking for the revision that contained them turned up nothing: they appear in no revision of the server-side validation page back to the 2024 migration. The string set has been a stable seven the whole time.
So the claim was dropped rather than published, and the note that produced it was corrected. The reason to mention this at all is that it is the same failure mode as everything above — a plausible claim, held in good faith, that nobody had checked against the source.
Two things worth taking from this
If a vendor's documentation is in a public repository, its history is evidence. You can date a claim, diff a definition, and establish whether the page you are reading was written during a window when the source itself was wrong. This took an afternoon and settled several arguments that had been running on assertion.
Put a real date on technical pages. Not a freshness signal — an actual date, next to the revision you checked against. It is the only thing that lets a reader work out whether your page predates a correction. Every page on this site carries one for that reason, and the ones that quote a moving target say which revision they quote.
The uncomfortable corollary: this page will age too. It describes the state of a table on 25 August 2026. If you are reading it much later, run the curl at the top yourself — that is the point of showing it.
Common questions
It is a public repository, so fetch the file at a specific commit through raw.githubusercontent.com. The one caveat that catches people is that the default branch is production, not main. From there it is ordinary git archaeology: list the commits touching a file, fetch it at each, and diff.
The 100010, 102010, 103010, 104010, 105010, 106010 and 120010 families appear only in the 19 December 2025 revision — about twenty codes documented for seventy-seven days. Separately, 110420, 110430, 110500, 110510, 200010, 400030 and 400040 were redefined in that same revision and then deleted by March 2026.
The current table collapses that whole family to a 300* wildcard with a note that the remaining digits are for internal use. So 300030 has no individual entry, and neither does 600010 beyond one parenthetical — which is why the two most-searched Turnstile errors have no official definition to look up.
Much of it, yes. Anything written between December 2025 and March 2026 from the official source will carry codes that no longer exist and definitions that were later reverted, and there was no announcement when they were removed. Check the date on any page describing a Turnstile error code, and check what it says about 400020.
Related
Sources
- Cloudflare — the current client-side error codes
- cloudflare/cloudflare-docs — the repository whose history this is drawn from
- PR #27237 — the 19 December 2025 rewrite that added the codes
- Issue #27864 — the bug report filed against the wrong 400020 definition
- PR #27880 — the 29 January fix that deepened it
- PR #28831 — the 6 March 2026 revert
Automating a gate you own or are authorised to test?
// SolveGate clears Cloudflare Turnstile and WAF challenges through one REST call · first 1,000 solves free