Why Your Valid Captcha Token Keeps Getting Rejected
A valid token fails when the session that earned it is not the session that spends it. The four mismatches, in order of frequency, and how to fix them.
A captcha token can be perfectly valid and still be rejected. The solver did its job, the token is well-formed and unexpired, and the target refuses it anyway. Nine times out of ten the cause is the same: the session that earned the token is not the session that spent it.
This is the most expensive failure in automation, because every signal points at the wrong place. The solver reports success. The token looks right. So teams switch providers, find the same rate, and switch again — when the fix was three fields in the request they were already making.
What "session mismatch" actually means
When a challenge issues a token, it is not certifying a string. It is certifying a context: this browser, from this address, with these characteristics, behaved like a human at this moment. The token is a receipt for that context.
Submit it from a different context and the validator sees a receipt that does not match the customer presenting it. It has no way to distinguish that from a stolen token, so it refuses — and because refusing is the safe default, it refuses without explaining.
The four mismatches, in order of frequency
1. The exit IP differs
By far the most common. The solver minted the token behind its own address; you submit from yours. For reCAPTCHA v2 this degrades acceptance. For score-based and session-graded systems it is usually fatal.
Fix: pass your proxy through on the solve request so the token is minted behind the same exit IP that will spend it. If a provider does not accept a proxy parameter, it cannot solve session-graded challenges correctly, whatever its documentation claims.
2. The user agent differs
Cloudflare Turnstile binds tokens to a user agent explicitly; others weight it as a signal. Minting with one and submitting with another is a visible inconsistency.
Fix: use the user agent returned alongside the token, not your own default. Any provider that does not return one is withholding something you need.
3. The action name differs
Score-based challenges such as reCAPTCHA v3 grade per action. The page declares an action — login, checkout — and the score is issued against it. Request a token without that action, or with a different one, and the score is discounted at verification even though a token comes back.
Fix: read the action the page reports and send it with the request. See our reCAPTCHA v3 guide for how scores are graded.
4. The token expired
Most tokens live around two minutes. Teams request one at the start of a long workflow and submit it several steps later.
Fix: request the token immediately before submitting, not in advance. If your workflow cannot guarantee that, restructure it so the solve is the last step before the POST.
A diagnostic order that saves time
Work through these in sequence. Each one eliminates a class of cause, and most teams stop at step two.
- Is a proxy being passed on the solve request? If not, add it and re-measure before changing anything else.
- Is the returned user agent being replayed on submission? Log both and compare them as strings.
- For score-based challenges, does the action match what the page declares? Capture it from the page rather than assuming.
- How long between mint and submit? Log the delta. Anything over a minute is suspect.
- Only now consider the provider. If all four are clean and acceptance is still poor, you have a real capability problem rather than a configuration one.
Why the error messages do not help
Verification endpoints return almost nothing — a generic failure, sometimes a code that maps to several unrelated causes. That is deliberate: a detailed error is a debugging tool for whoever is trying to defeat the system.
So you cannot debug this from the response. You have to debug it from your own logs, by recording what you sent and comparing it to what you received. Log the proxy used, the user agent returned, the action sent and the mint-to-submit delta on every request. Without those four fields you are guessing.
Measure accepted completions, not returned tokens
Most teams track solve success as reported by the provider. That number is close to useless on its own, because it measures whether a token was produced, not whether it worked.
Track accepted completions — requests where the target accepted the token and the workflow continued. The gap between those two numbers is exactly the session-mismatch problem, and it is the only metric that tells you whether your integration is healthy. It is also the right basis for comparing providers, as our benchmarks page explains.
How we handle it
Every solve accepts a proxy and user agent, and every response returns the user agent the solution is bound to so you can replay it exactly. For DataDome we refuse a request that arrives without a proxy rather than return a cookie that cannot work — a failed request is more useful than a plausible-looking result that fails silently later. Full field reference in the API docs.
Frequently Asked Questions
Why is my captcha token rejected even though it is valid?
Almost always because the session that earned it differs from the session submitting it. A token certifies a context — a browser, an exit IP, a set of characteristics — not just a string. Pass your proxy and the returned user agent through so the minting context matches the submitting one, and most rejections disappear.
How long is a captcha token valid?
Typically around two minutes, though it varies by challenge type. The practical implication is that you should request the token immediately before submitting rather than at the start of a longer workflow. If several steps sit between solve and submit, restructure so the solve happens last.
Do I always need a proxy to solve captchas?
Not always, but it is the single biggest lever on acceptance. For token-based challenges like reCAPTCHA v2 it is optional and improves results. For session-graded systems such as DataDome it is mandatory, because the result is bound to the exit IP that earned it and will fail immediately otherwise.
What is the difference between solve rate and acceptance rate?
Solve rate measures whether the provider returned a token. Acceptance rate measures whether the target actually accepted it and your workflow continued. Only the second one matters commercially, and the gap between them is where session-mismatch problems hide. Track acceptance in your own logs rather than trusting provider dashboards.
Why do verification errors give so little detail?
Because detailed errors would be a debugging tool for attackers. Verification endpoints deliberately return generic failures, so you cannot diagnose from the response. Log the proxy used, the user agent returned, the action sent and the delay between mint and submission, then diagnose from your own records.
Fix the four fields first
Before changing providers, log those four values on a hundred requests and compare. If you want to test against a service that returns everything needed to replay a session, start a free trial.