cf_clearance cookie?Short answer: cf_clearance is the cookie Cloudflare sets on your browser after it has decided you are not a bot. It is not a token you solve — it is a receipt issued by Cloudflare's edge, stamped with the challenge you passed, bound to your IP address and user agent, and valid for a limited time (30 minutes by default). Everything that goes wrong with it later goes wrong for one of those three reasons.
The word "receipt" is the part people skip. A token answers a question your origin asks. A receipt records that a connection finished something at the edge — which is why copying it into a different connection, from a different program, on a different address, produces a challenge rather than a 200.
The cookie appears only after one of three challenge types completes:
cf_clearance is set separately by Cloudflare's edge on the same request flow.That distinction matters: teams routinely pay for a Turnstile token, paste it into a header, and wonder why the page is still a challenge page. The token answers "a human solved the widget"; the cookie answers "this connection finished the challenge".
The value looks like an opaque string of roughly 40–60 characters plus a dotted suffix, and it is signed. Cloudflare does not publish the format, but the practical implication does not depend on the internals: you cannot mint one client-side without executing the challenge, and you cannot move one between machines without it dying.
| Bound to | What happens if it changes |
|---|---|
| IP address | Clearance is dropped at once; you get the challenge again. This is why rotating proxies makes blocking worse, not better. |
| User agent / TLS fingerprint | Same effect. A browser-issued cookie replayed from requests usually dies on the fingerprint alone. |
| Zone | A cookie from one site never works on another, even behind the same Cloudflare account. |
| Time | Default lifetime is 30 minutes. Session-scoped cookies disappear when the browser closes; a stale cookie is worse than none, because it signals a replay. |
__cf_bm — bot management telemetry, not clearance. It is set routinely and proves nothing.cf_chl_2 / cf_chl_prog — transient state of the challenge currently running. If you see these, you have not passed yet.cf_clearance — the only one that means "past the edge".There is a fourth thing worth separating: the cf_clearance cookie is not the same as the cf-mitigated response header, which tells you the response was produced by the edge rather than your origin. Seeing that header means the challenge was served; it says nothing about whether you passed it. The related __cf_bm cookie has its own page for the same reason — it is easy to test for the wrong one.
The shape that works is one session, one exit, one client stack. Pass the challenge once, then keep using that exact context.
from playwright.sync_api import sync_playwright
with sync_playwright() as p:
browser = p.chromium.launch()
ctx = browser.new_context(proxy={"server": PROXY}) # pin the exit
page = ctx.new_page()
page.goto(url)
# A JS or Managed Challenge resolves inside the page; wait for it to settle
# rather than polling the same URL from a second client.
page.wait_for_load_state("networkidle")
jar = {c["name"]: c["value"] for c in ctx.cookies()}
print("turnstile" in jar or "cf_clearance" in jar, sorted(jar))
# Reuse through this context, not by exporting the header elsewhere.
resp = ctx.request.get(api_url)
print(resp.status, resp.headers.get("cf-mitigated"))
import time, requests
# If you must carry the cookie by hand, carry the identity with it.
s = requests.Session()
s.headers.update({
"User-Agent": SAME_UA_AS_THE_BROWSER,
"Accept-Language": "en-US,en;q=0.9",
})
s.cookies.set("cf_clearance", VALUE, domain="example.com")
s.proxies = {"http": EXIT_IP, "https": EXIT_IP} # the exit that earned it
issued = time.time()
r = s.get(url)
if r.status_code in (403, 503) and "cf-mitigated" in r.headers:
# Refused at the edge: the cookie is expired, or the exit/UA changed.
reissue = time.time() - issued > 25 * 60
print("expired" if reissue else "fingerprint or IP mismatch")
There are three honest paths, and the third is the one people skip:
cf_clearance for a given site key and URL is the usual route; SolveHub exposes one REST endpoint for Cloudflare interstitial and Turnstile tasks and bills per completed task. Whatever service you use, check that the returned cookie is paired with the same proxy exit that will make the real requests.requests header set — dead on the TLS fingerprint.The fix is architectural, not a better solver: pin one session to one exit IP, one fingerprint and one cookie, and refresh the whole triple when the cookie expires.
| What you see | What it usually means | First thing to change |
|---|---|---|
403 with a challenge page and cf-mitigated: challenge | The edge served a challenge instead of your origin. You have no valid clearance for this connection. | Check the cookie's age and the exit IP before changing anything else. |
403 with cf-mitigated: challenge and a fresh cookie | The cookie is not accepted: IP, UA or TLS changed between issuance and use | Re-issue from the same client stack that will make the requests |
1020 in the page body | A firewall rule blocked the request outright — not a challenge, not solvable | Different rule, different path. A clearance cookie cannot fix an access rule. |
429 or intermittent challenges under load | Rate-based rules, or the session looks like several clients sharing one cookie | One worker per cookie; slow down before rotating anything |
200 on HTML, 403 on the JSON endpoint | The API path has a separate rule set from the page | Check whether the endpoint needs clearance at all — many do not |
Does cf_clearance work on a different subdomain? No. Clearance is per hostname and zone.
Can I generate it without a browser? Not by computing it. Only by completing the challenge, which needs a JS engine or a service that runs one for you.
Why do I get a 403 with a valid-looking cookie? Usually IP or user-agent drift between issuance and use. Log both on both sides before blaming the solver.
How long does it actually last? Thirty minutes by default, but that is the configured value rather than a constant: zones can set shorter or longer. Treat the Expires on the cookie as the ceiling and expect the edge to challenge earlier if your traffic pattern changes.
Is a Turnstile token the same thing? No. The widget token is verified by your origin; cf_clearance is set by the edge. Paying for one does not give you the other, and sending the token as a cookie does nothing.