"Turnstile token rejected" — what the site is really telling you
No part of Cloudflare emits the phrase "token rejected". It is what an application prints after siteverify has told it no, which means the message you are reading has been through one translation already.
Where the phrase comes from
Turnstile has two halves. The widget in the browser issues a token; the site's own server then asks Cloudflare whether that token is genuine, through the siteverify endpoint. Cloudflare answers with success: true or with a code such as invalid-input-response or timeout-or-duplicate.
"Token rejected", "invalid Turnstile token" and "Turnstile verification failed" are all wording chosen by the application around that answer. Two sites hitting the same underlying cause will phrase it differently, which is why searching the exact sentence rarely finds anything useful.
That matters for diagnosis: the message tells you the site's server refused to accept the token. It does not tell you why, and the site usually has the real code in its logs.
If you are a visitor and cannot get through
There is nothing to fix on your side in most cases, but these are the ones where there is:
| Try this | Why it helps |
|---|---|
| Reload and submit promptly | A token is valid for 300 seconds. A form left open past that fails even though the widget showed a tick. |
| Do not submit twice | Each token validates exactly once. Re-sending a form that appeared to fail spends an already-spent token and produces the same message again. |
| Check the clock | A device whose time is significantly wrong can have its token judged expired on arrival. |
| Allow challenges.cloudflare.com | Content blockers, strict privacy modes and some corporate proxies stop the widget's script, so the field is never filled in at all. |
| Try without extensions | Script-rewriting extensions can break the widget without any visible sign that they have. |
If none of that helps, the fault is on the site's side and only they can fix it. Some communities hit this in waves — players reporting it on the same game at the same time is a site-side problem, not five hundred simultaneous browser misconfigurations.
If you are the developer, find the real code
Log what siteverify actually returned. The error-codes array in its response is the diagnosis; your own message is a paraphrase of it.
curl -X POST https://challenges.cloudflare.com/turnstile/v0/siteverify \ -d secret="$TURNSTILE_SECRET_KEY" \ -d response="$TOKEN" # {"success":false,"error-codes":["timeout-or-duplicate"]} # ^ this is what to act on
| If error-codes says | Then |
|---|---|
| invalid-input-response | The token was expired, empty, mangled or never real. Check the gap between issue and validation first. |
| timeout-or-duplicate | The token was already spent. Usually a retry, a double submit, or validating twice in your own code. |
| invalid-input-secret | Your secret is wrong — nothing to do with the visitor at all. |
| missing-input-response | The field never reached your handler. A naming mismatch between the form and the server. |
Printing the code, or a short reference to it, in the message the user sees turns an unactionable sentence into a supportable one.
The cause that produces the most reports
A single-page app or a form inside a modal renders the widget once, then re-renders the form without re-rendering the widget. The hidden field is empty on the second attempt, so the server gets nothing and reports a rejected token.
The fix is to render explicitly and reset deliberately: call turnstile.reset() when a submission fails, so a fresh token is issued rather than a spent one being resubmitted. Sites that do not do this generate a rejection on every retry, which is why users report that it "never works" while the site's own tests pass.
Common questions
No. Cloudflare returns machine-readable codes such as invalid-input-response and timeout-or-duplicate. "Token rejected" is wording the site chose to describe that answer, which is why the same underlying problem appears as a dozen different sentences across the web.
Because each token validates exactly once. If the first submission failed for an unrelated reason and the page resubmitted the same token, the second attempt fails as already-spent. A site that resets the widget between attempts does not have this problem.
It can contribute. The widget may score you differently from an unusual address, and some networks interfere with the script that loads it. But the message itself comes from the server-side check, so a VPN is a plausible contributing cause rather than a direct one.
Reload, submit promptly, do not double-submit, allow challenges.cloudflare.com, and check your clock. If it persists, it is the site's configuration and only they can address it — report it with the time and the page rather than trying more browser changes.
Log the error-codes array from your siteverify response. It names the cause precisely. Everything else is guesswork, and the array is one field you are already receiving and probably discarding.
Almost never on its own. Expiry, double submission and un-reset widgets account for the overwhelming majority. A sustained pattern of tokens that were never valid is a different signal from an occasional rejection during ordinary use.
Related
Sources
More in Turnstile errors
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