# Cloudflare Turnstile Error Codes: 110200, 300xxx, 600xxx

> What each Cloudflare Turnstile widget error code means, from 110100 to 600xxx: Cloudflare's current table, which errors to retry, and how to fix each one.

- Source: https://zerocaptcha.io/blog/cloudflare-turnstile-error-codes
- Published: 2026-09-30
- Updated: 2026-10-01
- Author: ZeroCaptcha Engineering

Cloudflare Turnstile's client-side error codes are six-digit numbers the widget reports when it
cannot produce a token: "An error callback will retrieve an error code as its first parameter",
and without an error callback the widget throws a JavaScript exception. The first three digits
name the family: `110xxx` for widget configuration (such as `110200`, "Domain not authorized"),
`200xxx` for clock, cache and iframe problems, `400xxx` for sitekey problems, and `300*` and
`600*`, both "Generic challenge failure" with the note "Bot behavior detected." In Cloudflare's
current table, updated 25 September 2026, only the two timeouts (`110600`, `110620`), the iframe
error (`200500`) and the `300*` and `600*` families are marked as worth a retry.

These are the widget's errors, in the browser. The errors a site's server gets when it verifies a
token are a different list, covered in
[Cloudflare Turnstile siteverify errors](https://zerocaptcha.io/blog/cloudflare-turnstile-siteverify-errors).

## How Cloudflare Turnstile error codes are built

Cloudflare's rule: "the first three digits indicate the error family (such as configuration
issues, network problems, or challenge failures), and the remaining digits specify the exact error
within that family." And: "When an error code is marked with `*`, the remaining digits can vary
and are for internal use." So any code that starts with `300` or `600`, whatever its last three
digits, belongs to a challenge-failure family, and the last three digits carry no public meaning.

The widget also retries on its own: "By default, Turnstile will automatically retry upon
encountering a problem". The `retry` option is `auto` by default and `never` turns it off, and
`retry-interval` defaults to 8,000 ms.

## The current table (checked 1 October 2026)

Descriptions and troubleshooting text are Cloudflare's.

| Code | Description | Retry | Cloudflare's troubleshooting |
| --- | --- | --- | --- |
| `110100` | Invalid sitekey | No | Verify the sitekey in Cloudflare dashboard. |
| `110110` | Sitekey not found | No | Check sitekey spelling and dashboard configuration. |
| `110200` | Domain not authorized | No | Add current domain in Hostname Management. |
| `110600` | Challenge timed out | Yes | "The visitor's clock may be wrong, or the challenge took too long." |
| `110620` | Interaction timed out | Yes | "The visitor did not interact with the widget in time. Reset with `turnstile.reset()`." |
| `200100` | Clock or cache problem | No | "The visitor's clock is wrong or the challenge was cached by an intermediary." |
| `200500` | Iframe load error | Yes | "The Turnstile iframe could not load. Check if `challenges.cloudflare.com` is blocked." |
| `300*` | Generic challenge failure | Yes | "Bot behavior detected." |
| `400020` | Invalid sitekey | No | Verify the sitekey in Cloudflare dashboard. |
| `400021` | Sitekey domain mismatch | No | "Sitekey region does not match domain in the Turnstile script tag." |
| `400070` | Sitekey disabled | No | "The sitekey is disabled. Check the Cloudflare dashboard." |
| `600*` | Generic challenge failure | Yes | "Bot behavior detected." |

## What each family means in practice

### 110xxx: widget configuration and timeouts

`110100`, `110110` and `110200` come from the widget's setup, not from the visitor, so only the
site owner can fix them. For `110200`, the fix is in
Hostname Management: hostnames are fully qualified domain names without wildcards, "adding a
hostname automatically authorizes all of its subdomains", and the Free plan allows 10 hostnames
per widget. If you see `110200` on your own staging or local host, Cloudflare's testing sitekeys
"work on any domain, including: `localhost`, `127.0.0.1`, `0.0.0.0`".

`110600` and `110620` are timeouts. The first points at a wrong clock or a slow challenge; the
second at a visitor who did not click in time, fixed by `turnstile.reset()`.

### 200xxx: clock, cache and iframe

`200100` is a wrong clock or a challenge "cached by an intermediary". Cloudflare warns that
"Proxying or caching this file will cause Turnstile to fail when future updates are released":
load `api.js` from `https://challenges.cloudflare.com/turnstile/v0/api.js` itself.

`200500` means the widget's iframe could not load, and Cloudflare's first check is whether
something blocks `challenges.cloudflare.com`: an ad blocker, a network filter, or a Content
Security Policy without `https://challenges.cloudflare.com` in `script-src` and `frame-src`. Since 22 July 2026,
Turnstile may also call `hagen.challenges.cloudflare.com` and
`brunhild.challenges.cloudflare.com`, and Cloudflare asks for both on network allowlists. The
related "Please unblock challenges.cloudflare.com" message is covered in
[Please unblock challenges.cloudflare.com](https://zerocaptcha.io/blog/please-unblock-challenges-cloudflare-com).

### 400xxx: sitekey problems

`400020` (invalid sitekey), `400021` (sitekey region does not match the domain in the script tag)
and `400070` (sitekey disabled) are not retryable. As with `110xxx`, check the sitekey the page
really uses; [find a Cloudflare Turnstile sitekey](https://zerocaptcha.io/guides/find-cloudflare-turnstile-sitekey)
shows where it appears.

### `300*` and `600*`: challenge failure

Both families read "Generic challenge failure" and "Bot behavior detected." Cloudflare marks them
retryable, and the widget retries by default. A person on a normal browser who sees one should try
Cloudflare's troubleshooting points below. A script that sees one is being detected; see the last
section.

## Codes no longer in the table (historical)

Cloudflare's table was rewritten on 6 March 2026. The version in use before it, from January 2026,
listed families the live page no longer has. These meanings are historical: Cloudflare no longer
documents them, so treat them as context for old logs, not as current definitions.

| Family (historical) | Meaning in the January 2026 table |
| --- | --- |
| `100***` | "Initialization problems" (page reload needed) |
| `102***` | "Invalid parameters (network)"; for example `102020`, "Network timeout during challenge" |
| `103***` | "Invalid parameters (browser)"; for example `103030`, "Browser extension interference" |
| `104***` | "Invalid parameters (client-side)" |
| `105***` | "API compatibility" |
| `106***` | "Invalid parameters (general)" |
| `120***` | "Network or loading issues"; for example `120010`, "Script loading failed", and `120030`, "CDN unavailable" |

The old table also had `110420`, "Rate limiting active", and `110500`, "Browser not supported",
which are not in the current `110xxx` list either.

## Cloudflare's troubleshooting points

For errors a real visitor sees, Cloudflare lists these causes (verbatim):

- "Turnstile supports all major browsers, except Internet Explorer."
- "Some browser extensions, such as ad blockers, may block the scripts Turnstile needs to
  operate."
- "Turnstile requires JavaScript to run."
- "Some virtual private networks (VPN) or proxies may interfere with Turnstile."
- "Your current network may have restrictions causing Turnstile challenges to fail."

Cloudflare's compatibility checker is at `https://debug.challenges.cloudflare.com/`. A `401` in the
browser console is not one of these errors: it "often occurs when the widget attempts to request a
Private Access Token that your device or browser does not support yet", and can generally be
ignored.

## What the codes mean for automated browsers

When a widget in Playwright, Puppeteer or Selenium fails with a `300xxx` or `600xxx` code, it is
doing what Cloudflare documents. Its testing page says "Automated testing suites (like Selenium,
Cypress, or Playwright) are detected as bots by Turnstile", and its challenge docs say "Automated
browsers are not supported for solving production challenges." Retrying in the same automated
browser meets the same checks.

On your own site, use Cloudflare's testing sitekeys instead; see
[test Cloudflare Turnstile in CI](https://zerocaptcha.io/guides/test-cloudflare-turnstile-in-ci). On a site you are
allowed to automate but do not run, a solving API sidesteps the widget: your code reads the
sitekey, gets a token from the API, writes it into the `cf-turnstile-response` field and submits.
The widget's own result then stops mattering, as long as the page reads that field; pages that
take the token from a callback are covered in
[submit a Cloudflare Turnstile token](https://zerocaptcha.io/guides/submit-cloudflare-turnstile-token).
[Cloudflare Turnstile in headless browsers](https://zerocaptcha.io/blog/cloudflare-turnstile-headless-browser) explains
why automated browsers fail and shows that pattern in Playwright, and the
[Cloudflare Turnstile solver](https://zerocaptcha.io/cloudflare-turnstile-solver) page has it for other languages. A
solving API does not fix `110xxx` or `400xxx` errors: those are the site owner's configuration.
Use it only where you are permitted; see
[responsible captcha automation](https://zerocaptcha.io/guides/responsible-captcha-automation).

## Sources

- [Cloudflare Turnstile: client-side error codes](https://developers.cloudflare.com/turnstile/troubleshooting/client-side-errors/error-codes/)
  (last updated 25 September 2026; checked 1 October 2026).
- [Cloudflare Turnstile: client-side errors](https://developers.cloudflare.com/turnstile/troubleshooting/client-side-errors/)
  (checked 1 October 2026).
- [Previous version of the error-code table in Cloudflare's docs repository](https://raw.githubusercontent.com/cloudflare/cloudflare-docs/c1145371a3031d973f08dcfeae9015dcbfbd5363/src/content/docs/turnstile/troubleshooting/client-side-errors/error-codes.mdx),
  January 2026 (checked 1 October 2026).
- [Cloudflare Turnstile: widget configurations](https://developers.cloudflare.com/turnstile/get-started/client-side-rendering/widget-configurations/)
  and [client-side rendering](https://developers.cloudflare.com/turnstile/get-started/client-side-rendering/)
  (checked 1 October 2026).
- [Cloudflare Turnstile: hostname management](https://developers.cloudflare.com/turnstile/additional-configuration/hostname-management/)
  and [changelog](https://developers.cloudflare.com/turnstile/changelog/) (checked 1 October
  2026).
- [Cloudflare Turnstile: Content Security Policy](https://developers.cloudflare.com/turnstile/reference/content-security-policy/)
  (checked 1 October 2026).
- [Cloudflare Turnstile: testing](https://developers.cloudflare.com/turnstile/troubleshooting/testing/)
  and [Cloudflare challenges: supported browsers](https://developers.cloudflare.com/cloudflare-challenges/reference/supported-browsers/)
  (checked 1 October 2026).

## Questions

### What does Cloudflare Turnstile error 110200 mean?

Domain not authorized: the page's domain is not among the widget's hostnames. Retrying does not help; the site owner must add the domain in Hostname Management.

### What do Cloudflare Turnstile errors 300xxx and 600xxx mean?

Cloudflare lists both the 300* and 600* families as 'Generic challenge failure' with the note 'Bot behavior detected.' The last three digits vary and are for Cloudflare's internal use, and Cloudflare marks both as retryable.

### Where did Turnstile error codes like 100xxx and 120xxx go?

Cloudflare rewrote its error-code table on 6 March 2026 and dropped those families. The current table, last updated 25 September 2026, lists only 110xxx, 200xxx, 300*, 400xxx and 600* codes.
