“Why does my CAPTCHA token fail as expired or already used?”
Why does my CAPTCHA token fail as expired or already used?
Short answer
Because CAPTCHA tokens are one-time, time-limited proofs, by design. The verify call fails when the token was already consumed by an earlier verify, which catches double submits and retries, or when it expired before the call. CaptchaKit tokens live 10 minutes and work once: a replay returns success false with a Token already used error, an expired one returns Invalid or expired token. The fix is always the same: get a fresh token and verify once.
Side by side
Token lifetimes as documented by each provider, October 2026.
| Provider | Token lifetime |
|---|---|
| CaptchaKit | 10 minutes, one verify per token |
| Cloudflare Turnstile | 300 seconds, single use; a late or reused token fails with timeout-or-duplicate |
| Google reCAPTCHA | Two minutes, per the v3 developer docs |
| Wix CAPTCHA | 120 seconds, per the Wix tutorial |
One token, one decision
A CAPTCHA token is proof that a challenge was passed at a moment in time. To keep that proof meaningful, providers consume it on first verification, so the same token cannot vouch for two submissions. With CaptchaKit, a valid verify returns success true, and a second verify of the same token returns success false with a Token already used error. If your frontend retries a failed request, or a visitor double-clicks submit, the second attempt reuses the token and fails.
Handle it by playing again, not by loosening the check. The widget issues a new token each time the visitor passes.
Caching and slow visitors
The other common cause is time. A visitor passes the challenge, then fills in the rest of a long form or walks away; by the time they submit, the token is past its lifetime and the verify fails as expired. Pages that cache the rendered widget markup can serve stale state for the same reason. Read the token at submit time, from the widget's data-token attribute, and verify immediately.
For CaptchaKit specifically, the failure is visible in the response: success false with Invalid or expired token. Show a plain message that asks the visitor to try again; a fresh pass mints a fresh token.
A quick debugging order
Work through these in order and most cases resolve:
- Read the exact error string: Invalid or expired token versus Token already used tells you which failure you have.
- Log every verify call. Two calls for one submission is a client retry loop, not a provider problem.
- Confirm the token is actually attached: an empty gamecaptchaToken field fails before the provider sees anything.
- Check the keys: the siteKey in the body must be the one the token was issued for.
- Check your server clock and form flow for anything that delays the verify past the lifetime.
Questions
How long is a CaptchaKit token valid?
10 minutes, and it can only be verified once.
Can I verify the same token twice?
No. The second call returns success false with a Token already used error. Request a fresh pass instead.
Why does verification fail right after a pass?
Usually a double submit or an automatic retry that reuses the token. Log your verify calls to confirm.
How long do other providers' tokens last?
Turnstile documents 300 seconds, single use; reCAPTCHA tokens expire after two minutes; Wix's tutorial says 120 seconds.
Should I cache tokens for repeat submissions?
No. Each submission needs its own token, verified once.
What error does CaptchaKit return for a bad token?
success false, with Invalid or expired token or Token already used as the error.
Sources
- CaptchaKit documentation (checked 2026-10-18)
- Cloudflare Turnstile: validate the token (checked 2026-10-18)
- Google reCAPTCHA v3 docs (checked 2026-10-18)
- Wix tutorial: reCAPTCHA for data submission (checked 2026-10-18)
Related
Protect your forms with a game
Every arcade CAPTCHA we make. Sign up, grab your embed code, protect your forms today.
Get started →Pay what you want. Start free.