How Cloudflare Turnstile Works
Turnstile is Cloudflare's replacement for the puzzle CAPTCHA. It runs a set of small browser checks, hands the page a token, and the site's server asks Cloudflare whether that token is good. When it loops, one of those steps is failing, and the error code usually says which.
Read this first
- Turnstile has three widget modes (managed, non-interactive, invisible) and works on any site, with or without Cloudflare in front of it.
- A token is valid for 300 seconds and can be checked once. Many loops are expired or reused tokens, not suspicion.
- The widget's error codes separate configuration faults (wrong sitekey or domain), environment faults (clock, cache, blocked iframe) and outright bot detection (300 and 600 families).
- If you are testing your own forms, use Cloudflare's published test keys in staging instead of trying to automate a real challenge.
What Turnstile is
Cloudflare's Turnstile documentation calls it a "smart CAPTCHA alternative". Instead of asking the visitor to pick traffic lights, it runs short, non-interactive JavaScript checks in the browser. Cloudflare lists the kinds of checks it uses: proof-of-work puzzles, proof-of-space, probing for web APIs and other browser-environment signals. The outcome adapts to the visitor: most people see a spinner for a moment or nothing at all, and a smaller share are asked to tick a box.
Two properties surprise people. First, Turnstile does not require the site to route traffic through Cloudflare; the docs state it "can be embedded into any website without sending traffic through Cloudflare". A Turnstile loop on a site that is not on Cloudflare is still a Turnstile loop. Second, Turnstile is not the same thing as a Cloudflare WAF challenge page, the full-screen "verify you are human" interstitial a Cloudflare-proxied site can show. They share technology, and one can satisfy the other through pre-clearance (covered below), but they are configured in different places.
On Apple devices and some other browsers, Turnstile can also use Private Access Tokens, issued under the Privacy Pass HTTP authentication scheme, which let the device vouch for itself without revealing who the user is. Cloudflare's troubleshooting page notes that a 401 response in the console usually relates to this and can generally be ignored when a token is still issued.
Widget modes
A site owner picks one of three widget modes, defined on Cloudflare's widget concepts page. The mode changes what a visitor sees; the server-side check described in the next section is the same for all three.
| Mode | What the visitor sees | When it asks for interaction |
|---|---|---|
| Managed (recommended) | A widget that usually completes on its own | Shows a checkbox only when Cloudflare wants more evidence |
| Non-interactive | A visible widget with a loading spinner | Never |
| Invisible | Nothing; checks run in the background | Never (sites must reference Cloudflare's privacy addendum) |
Server validation
The browser side only produces a token. The site's backend has to send that token to Cloudflare's Siteverify endpoint, and the server-side validation guide is blunt about it: "The client-side widget alone does not protect your forms." Each token is valid for 300 seconds and can be validated once; a second check of the same token fails with timeout-or-duplicate.
A minimal, tested validation function in Python:
"""Validate a Turnstile token on your server before trusting the form it came with."""
import os
import requests
SITEVERIFY = "https://challenges.cloudflare.com/turnstile/v0/siteverify"
def verify(token: str, remote_ip: str | None = None, expected_hostname: str | None = None) -> tuple[bool, list[str]]:
payload = {"secret": os.environ["TURNSTILE_SECRET"], "response": token}
if remote_ip:
payload["remoteip"] = remote_ip
result = requests.post(SITEVERIFY, data=payload, timeout=10).json()
errors = result.get("error-codes", [])
if not result.get("success"):
return False, errors
if expected_hostname and result.get("hostname") != expected_hostname:
return False, ["hostname-mismatch"]
return True, errors
We ran it against Cloudflare's published test secrets on October 30, 2026. The always-pass secret returned success, the always-fail secret returned invalid-input-response, and the spent-token secret returned timeout-or-duplicate, which is the same code a real double submission produces.
Two server-side mistakes cause loops that look like bot detection: validating the token twice (once in middleware, once in the handler), and caching a page that contains a token so the next visitor receives a used one. Both fail with the duplicate error, and the fix is in the site's code, not the visitor's browser.
Why it loops
A loop means the widget keeps restarting instead of finishing. Cloudflare's client-side error codes and its challenge solve issues page together cover most causes. They fall into four groups.
The last group is the one people searching for help usually have, and Cloudflare's wording for it is short: if Turnstile suspects bot-like behavior, you may see repeated challenges. In our diagnosis work, the common triggers for real people are a privacy extension that alters browser APIs, a browser that is several versions out of date, a VPN or proxy exit with a poor reputation, and a WebRTC or time zone signal that contradicts the IP's location. For automated browsers, the triggers are the automation itself: navigator.webdriver, headless rendering differences and request patterns.
| Group | Typical codes or symptoms | What is actually wrong |
|---|---|---|
| Site configuration | 110100 or 400020 invalid sitekey; 110110 sitekey not found; 110200 domain not authorized; 400070 sitekey disabled | The widget is set up for a different domain or key. Visitors cannot fix it. |
| Time and caching | 110600 challenge timed out; 200100 clock or cache problem | The device clock is wrong, or an intermediary cached the challenge |
| Blocked resources | 200500 iframe load error; scripts blocked; JavaScript disabled | An extension, filter, corporate proxy or WebView blocks challenges.cloudflare.com |
| Bot detection | 300 and 600 families, "bot behavior detected" | The browser environment or its network looked automated |
Fixes by cause
Work through these in order. Each step removes one group from the table above.
- Confirm it is not the site. Open the same page in a second, clean browser on another network. If it loops everywhere, the site has a configuration error (the 110 and 400 codes) and only the site owner can fix it. Send them the code and the time.
- Fix the clock. Turn on automatic date and time on the device. A clock that is minutes off produces 110600 and 200100 errors that look random.
- Remove interference. Disable extensions, open a private window, and allow
challenges.cloudflare.comin any content blocker, DNS filter or corporate proxy. In mobile apps, the WebView must allow that domain and run JavaScript. - Update the browser. Turnstile supports all major browsers except Internet Explorer, but an outdated build is both a compatibility risk and an unusual signal.
- Check the network. If the loop appears only on a VPN or proxy, the exit is part of the problem. Run the WebRTC leak test and the DNS leak test to make sure the browser is not reporting a second location, and check the address type with the IP reputation check. Cloudflare itself suggests switching networks, for example to a mobile hotspot, to test this. If you route through a proxy on purpose, use one whose exit you control and do not share; Coronium's mobile proxies are dedicated carrier lines, one customer per device.
- Keep one session on one address. A browser that changes IP between loading the widget and submitting the form presents a token minted for a different connection context. If you rotate IPs, do it between sessions.
For Cloudflare blocks that are not Turnstile (error 1020, 1015 rate limiting, full-page challenges), our Cloudflare IP ban check explains how to read the Ray ID and which errors a visitor can resolve.
If you are running an AI agent or automated browser that keeps meeting Turnstile, the issue is identity, not configuration. See why AI agents get blocked for the verified-agent route.
Site owners and visitors
If you run the site
- Validate every token server-side, once, and check
hostnameandactionwhen your flow uses them. - Do not cache pages or API responses that embed a token.
- Turn on pre-clearance if you also use WAF challenges. The pre-clearance guide explains how a solved widget can issue a
cf_clearancecookie at an interactive, managed or non-interactive level, so the visitor is not challenged twice. The widget's hostname must match the zone, and the cookie lasts as long as the zone's challenge passage setting. - In staging and automated tests, swap in Cloudflare's test sitekeys and test secrets. They return a dummy token,
XXXX.DUMMY.TOKEN.XXXX, that only test secrets accept, so your end-to-end tests pass without anyone solving a challenge. Production secrets reject the dummy token, which keeps the shortcut out of production. - Use the managed mode unless you have a reason not to. It asks for interaction only when Cloudflare is unsure.
If you are the visitor
You cannot change the site's configuration, and you do not need to defeat anything. A working, current browser with a correct clock, no interfering extensions and an honest network connection passes Turnstile in the normal case. If it does not, send the site owner the error code shown in the widget; the 110 and 400 families are theirs to fix.
If you automate someone else's site
Turnstile exists so the site owner can decide who gets through. Solver services and token farms move the problem without solving it and usually breach the site's terms. If the data matters to your business, ask the owner for an API or a test environment, or verify your agent through Cloudflare's bot program.
Sources and review scope
Sources reviewed October 30, 2026. Vendor documentation, standards and public filings were checked on that date. Coronium sells mobile proxies; the vendors described here were not consulted, and descriptions of their systems rely on what they publish. Code examples ran against local fixtures or vendor test keys. Nothing here is a method for getting past a particular site.
- Cloudflare Turnstile overview
How Turnstile works, widget types, use without the Cloudflare proxy.
- Cloudflare Turnstile: Widgets
Managed, non-interactive and invisible modes.
- Cloudflare Turnstile: Server-side validation
Siteverify, 300-second validity, single use.
- Cloudflare Turnstile: Client-side error codes
Code families and retry guidance.
- Cloudflare Turnstile: Challenge solve issues
Visitor-side causes and fixes.
- Cloudflare Turnstile: Testing
Test sitekeys, test secrets and the dummy token. Used for the validation test on October 30, 2026.
- Cloudflare Turnstile: Pre-clearance
cf_clearance levels and WAF challenges.
- RFC 9577: The Privacy Pass HTTP Authentication Scheme
The standard behind Private Access Tokens.
Frequently asked questions
More on bot defenses and proxy errors
Each guide reads one vendor or one symptom from primary documentation and ends with the checks to run.
Related workflows
Read 1020, 1015 and challenge pages with the Ray ID.
What the Cloudflare block page means and who can lift it.
Short answers on blocks, fingerprints and proxy errors.
Identity, policy and the verified-agent route.
Where to get a dedicated line
A Coronium mobile proxy is one physical device with its own SIM, rented to one customer. It connects over HTTP or SOCKS5, the IP changes by dashboard button, API link or timer, and data is not metered on dedicated lines. Brazil lines are the exception: 20 GB of data a month and a new IP on request only, with no timer. Stock and prices differ by country and carrier.