The cf_clearance cookie, explained
cf_clearance is the cookie Cloudflare sets in a browser to record that a client passed Cloudflare's client-side verification — an interstitial challenge page, JavaScript Detections, or a Turnstile widget with pre-clearance enabled. Cloudflare's edge reads it on later requests to the same zone and skips re-challenging while the clearance is still valid, for a period governed by the zone's Challenge Passage setting, which defaults to 30 minutes.
What issues the cf_clearance cookie
The cookie comes from Cloudflare's Challenge Platform, not from the origin server. Cloudflare documents three paths that produce it:
Once a session exists, Precursor — Cloudflare's session-based verification loop — keeps updating the same cookie with fresh behavioural signals rather than evaluating a single point in time.
What the cookie represents
Cloudflare describes cf_clearance as proof that "the visitor is a verified human and has passed Cloudflare's client-side verifications." It carries two things at once: *challenge clearance*, granted when a challenge is solved, and *precursor clearance*, refreshed continuously from session behaviour.
Clearance is graded. The level you hold determines which challenge types you skip, and a higher level supersedes a lower one. If a visitor later meets a challenge above their level, they solve it again.
| Clearance level | Turnstile pre-clearance value | Bypasses |
|---|---|---|
| Interactive (high) | interactive | All challenge types |
| Managed (medium) | managed | Managed and non-interactive challenges |
| Non-Interactive (low) | jschallenge | Non-interactive challenges only |
| None | no_clearance (default) | Nothing — no clearance cookie is issued |
For JavaScript Detections specifically, the outcome surfaces to your rules as the cf.bot_management.js_detection.passed field. Note the enforcement gap Cloudflare calls out: a false result blocks nothing on its own. You have to write a WAF custom rule against that field for it to matter.
How long cf_clearance lasts
There is no single universal TTL. The lifetime of a challenge clearance is the zone's **Challenge Passage** setting, which the site owner controls from Security Settings. Cloudflare documents the default as 30 minutes and recommends a value between 15 and 45 minutes.
- Cloudflare adds extra minutes during validation to absorb clock differences between client and edge.
- For XmlHTTP requests, an additional hour is included, so pages with short Challenge Passage settings do not break mid-session.
- JavaScript Detections has its own lifespan of 15 minutes, with the script re-injected before the session expires.
- Challenge Passage does not apply to rate limiting rules.
- Precursor can cut the effective clearance short at any point if it judges the session suspicious.
Do not hardcode a cf_clearance TTL. 30 minutes is a per-zone default, not a guarantee — the site owner can change it, and Cloudflare can shorten the effective clearance before the cookie's own expiry. Read the clearance as valid until the edge challenges you again, not until a timer you kept locally runs out.
How the cookie is bound
Cloudflare's own statement is short: the cookie is "securely tied to the specific visitor and device it was issued to, preventing reuse across machines." The inputs behind that binding are not published. Client IP, User-Agent string and TLS/JA3 fingerprint are all commonly asserted as binding factors; none of them appear in Cloudflare's documentation, so treat the binding as opaque and measure the behaviour against your own property rather than trusting a blog post.
What Cloudflare does document about the cookie's shape and scope:
- Attributes are
SameSite=None; Secure; Partitioned, so challenge state survives cross-site requests while complying with CHIPS. In a third-party context the cookie is stored in a partition keyed to the top-level site. - HTTPS is effectively required. Cloudflare warns that sites not using HTTPS may have problems with
cf_clearance. - The cookie cannot exceed 4096 bytes.
- For Turnstile pre-clearance, the widget's hostname must match the zone that holds the WAF rules, otherwise the clearance does not apply where you want it.
One detail is worth reading closely. Cloudflare advises site owners to "add a rate limiting rule based on the cf_clearance cookie value" so that "a single, valid cookie cannot be abused by one machine to send an excessive volume of requests." The mitigation exists because a live cookie is replayable within the client that holds it — volume, not possession, is what the platform expects operators to police.
What invalidates cf_clearance
- **Expiry.** The Challenge Passage window elapses.
- **Precursor re-evaluation.** If the session looks automated, effective clearance "may be reduced or invalidated" and additional challenges fire even though the cookie has not expired.
- **A higher-level challenge.** Non-interactive clearance does not carry you through a managed or interactive challenge; you solve again and the clearance is upgraded.
- **The cookie never lands.** No HTTPS, cookies blocked, or a partition mismatch in a third-party context all leave the client with nothing to send.
- **Scope mismatch.** Clearance obtained for one zone does not answer a challenge on another.
- **Broken client-side execution.** Blocked scripts, disabled JavaScript, unsupported browsers and unstable connections stop the challenge from completing, which Cloudflare lists among the causes of challenge loops.
To tell a challenged response from a real one, read the cf-mitigated header. Cloudflare documents challenge as its only valid value, across all Challenge Page types, and notes that challenged responses come back with a text/html content type regardless of what you requested.
const response = await fetch("https://example.com/api/orders", { credentials: "include", }); if (response.headers.get("cf-mitigated") === "challenge") { // The edge challenged this request. The body is an HTML challenge page, // not your JSON payload. Clearance is gone or was never established. throw new Error("challenged by Cloudflare"); } const data = await response.json();
cf_clearance versus a Turnstile token
They are produced by the same platform and are constantly confused, but they travel in different directions and are read by different parties. A Turnstile token is something your application verifies. A cf_clearance cookie is something Cloudflare verifies.
| Turnstile token | cf_clearance cookie | |
|---|---|---|
| Form | Opaque string, submitted in the cf-turnstile-response field | HTTP cookie |
| Who validates it | Your server, via the siteverify API | Cloudflare's edge, on each request |
| Endpoint | POST https://challenges.cloudflare.com/turnstile/v0/siteverify | None — read at the edge |
| Lifetime | 300 seconds from generation | Challenge Passage setting (30 minutes by default) |
| Reuse | Validated once; a replayed token is rejected (timeout-or-duplicate) | Presented on many requests until it expires or is invalidated |
| Size limit | 2048 characters | 4096 bytes |
| Transport | You submit it deliberately | The browser attaches it automatically |
Pre-clearance is the bridge between the two: a widget configured with interactive, managed or jschallenge issues the cookie alongside the token. Cloudflare is explicit that this does not remove your server-side obligation — the token still has to be enforced with siteverify. Widgets also fire an expired-callback when the 300-second token lapses, which is your cue to get a fresh one before submitting.
A third cookie shows up in the same traffic and is unrelated to clearance: __cf_bm is set by Cloudflare's bot protection to carry an encrypted bot-score calculation, and it expires after 30 minutes of continuous inactivity. Deleting or forging it does not affect challenge clearance.
Working with clearance in automated tests
Everything below assumes you are driving a property you own or are authorised to test — QA, CI, uptime monitoring, staging, or verifying your own anti-bot configuration. That is the boundary; run these techniques against someone else's site and you are on your own.
- Keep a cookie jar per logical client and let it persist across the whole test run. Discarding cookies between requests forces a challenge on every hop.
- Keep the client context stable for the life of the clearance. Cloudflare binds the cookie to the visitor and device it issued to, so rotating browser identity mid-session is the fastest way to lose it.
- Check
cf-mitigatedrather than parsing HTML. It is the documented signal and it works for XHR and fetch, where a challenge page would otherwise land in your JSON parser. - Do not cache clearance across environments or zones. Staging and production are different zones with different Challenge Passage settings.
- Budget for re-challenge. Precursor can invalidate a session that still holds an unexpired cookie, so treat a challenge mid-run as normal control flow, not an error state.
When a test needs a fresh Turnstile token instead of a browser session, SolveGate returns one from a single call. POST /v1/solve takes a gate of turnstile or waf, plus the sitekey and url, authenticated with a bearer secret key. Tokens typically come back in under 1.5 seconds; GET /v1/solve/{id} polls a job and is free. SolveGate covers Cloudflare Turnstile in its managed, non-interactive and invisible modes, and Turnstile-backed WAF challenge pages. It does not solve reCAPTCHA, hCaptcha, GeeTest, FunCaptcha or AWS WAF.
curl -s https://api.solvegate.io/v1/solve \ -H "Authorization: Bearer $SOLVEGATE_KEY" \ -H "Content-Type: application/json" \ -d '{ "gate": "turnstile", "sitekey": "0x4AAAAAAA...", "url": "https://staging.example.com/login" }'
Credits are prepaid, from $0.40 per 1,000 solves down to $0.075 at volume. Failed solves are never billed, and the first 1,000 solves are free. SDKs are published as solvegate on npm (Node 18+) and PyPI (Python 3.9+).
Common questions
For as long as the zone's Challenge Passage setting allows. Cloudflare documents 30 minutes as the default and recommends a value between 15 and 45 minutes, but the site owner sets it. Validation adds a few extra minutes to absorb clock skew, and an extra hour for XmlHTTP requests. Cloudflare can also cut the clearance short before the cookie expires if Precursor decides the session is suspicious, so no fixed TTL is safe to assume.
Cloudflare does not publish the binding inputs. The documented statement is that the cookie is "securely tied to the specific visitor and device it was issued to, preventing reuse across machines." IP address, User-Agent and JA3 fingerprint are widely claimed as binding factors but appear nowhere in Cloudflare's documentation. Treat the binding as opaque and test the behaviour on a property you control.
No. A Turnstile token is a one-shot string in the cf-turnstile-response field that your own server validates through the siteverify API within 300 seconds. cf_clearance is a cookie the browser sends back to Cloudflare's edge on subsequent requests, valid for the Challenge Passage window. A Turnstile widget with pre-clearance enabled issues both — and you still have to verify the token server-side.
Common causes are the clearance expiring, Precursor reducing or invalidating it after judging the session automated, or hitting a challenge above your clearance level — non-interactive clearance does not carry you through a managed or interactive challenge. The cookie may also never be stored at all: it requires Secure and HTTPS, and in third-party contexts it is partitioned by top-level site. Blocked scripts, disabled JavaScript and unsupported browsers stop the challenge from completing in the first place.
Cloudflare states the cookie is tied to the visitor and device it was issued to, and describes reuse across machines as prevented. Cloudflare separately advises site owners to rate limit on the cf_clearance value so a single valid cookie cannot be used by one machine to send excessive volume, which tells you volume is policed even inside the client that legitimately holds the cookie.
cf_clearance stores proof of a passed challenge and controls whether the edge challenges you again. __cf_bm is set by Cloudflare's bot protection and carries an encrypted bot-score calculation; it expires after 30 minutes of continuous inactivity and a separate one is generated per site. They are independent, and __cf_bm has no role in challenge clearance.
Related
More in Glossary
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