# Cloudflare 5-Second Challenge: What It Is Now and How to Pass It

> The Cloudflare 5-second challenge is the old name for its JavaScript challenge page. What replaced it, how to recognise it, and how to pass it with an API.

- Source: https://zerocaptcha.io/blog/cloudflare-5-second-challenge
- Published: 2026-10-03
- Author: ZeroCaptcha Engineering

The **Cloudflare 5-second challenge** is the old name for Cloudflare's JavaScript challenge: the
interstitial page that checked a visitor's browser for a few seconds before the site loaded, then
let it through with a `cf_clearance` cookie. The name stuck; the page changed. Today a site's WAF
rule shows a **Managed Challenge** or a **Non-Interactive Challenge** (API value `js_challenge`) in
its place, which Cloudflare says "typically takes less than five seconds", and Under Attack mode
"determines whether to block or allow a visitor within five seconds". Whatever it is called, it
is passed the same way: by a browser that runs it to the end, or by a challenge task that does, and
the result is the `cf_clearance` cookie.

This article covers what the name refers to today, how to recognise the page from code, why waiting
does not help, and the full request that passes it, as Cloudflare documented it on 1 October 2026.
Only automate sites you are allowed to: see [responsible captcha
automation](https://zerocaptcha.io/guides/responsible-captcha-automation).

## Where the name comes from

Cloudflare's JavaScript challenge was an interstitial page: the browser ran a script, waited a few
seconds while the page said it was checking the browser, then reloaded into the site. People named
it after the wait, and the name travelled: scraping forums still say "5-second challenge", "5 sec
challenge" or, in Chinese-language ones, 5秒盾, the "5-second shield".

Cloudflare's current names for the same job:

| What people call it | Cloudflare's name today | API value | Who shows it |
| --- | --- | --- | --- |
| The 5-second challenge, the JS challenge | Non-Interactive Challenge | `js_challenge` | A WAF custom or rate limiting rule with that action |
| The 5-second challenge, "Just a moment..." | Managed Challenge | `managed_challenge` | A WAF rule with that action; Under Attack mode |
| "Checking your browser before accessing..." | The interstitial challenge page of Under Attack mode | (security level) | Under Attack mode |

The Managed Challenge is the one Cloudflare recommends for most rules: it chooses per request
between a non-interactive check and one that asks for an interaction, such as a click. The
[Cloudflare challenge types](https://zerocaptcha.io/blog/cloudflare-challenge-types) article compares all three, with
the clearance levels between them.

## How to recognise it from code

A 5-second challenge, in any of its current forms, answers the first request with:

- HTTP status `403`;
- the header `cf-mitigated: challenge`, which Cloudflare sets on every challenge page;
- an HTML body, whatever the request asked for, titled "Just a moment..." in our checks, that loads
  its scripts from the site's own `/cdn-cgi/challenge-platform/` path.

A Block is different: also `403`, but no `cf-mitigated` header, and usually a 1xxx error code such
as [1020](https://zerocaptcha.io/blog/cloudflare-error-1020) in the body. No clearance lifts a Block. The [Cloudflare WAF
bypass](https://zerocaptcha.io/blog/cloudflare-waf-bypass) article sorts every response a WAF can give.

## Why waiting five seconds does not work

The old page looked like a timer, so a common first attempt is to sleep five seconds and ask again.
It does not work, because the wait was never the check. The page runs Cloudflare's checks in the
browser, posts the result to `/cdn-cgi/challenge-platform/`, and only then does Cloudflare set the
`cf_clearance` cookie. A client that runs no JavaScript, such as curl or Python's requests, gets the
same challenge page every time, however long it waits.

Two things do get through, on sites you may automate:

1. **A real browser that passes the page,** then keeps its cookie. Cloudflare notes that browser
   automation frameworks such as Playwright and Puppeteer "are not supported for solving production
   challenges", so an automated browser may never pass; see [Playwright and "Just a
   moment"](https://zerocaptcha.io/blog/playwright-cloudflare-challenge).
2. **A challenge task** that passes the page through your own proxy and hands you the cookie with
   the user agent it was issued for.

## Passing it with one request

ZeroCaptcha's CloudflareChallengeTask takes the page's URL and your proxy, and returns the cf_clearance cookie with the user agent it was issued for.
The proxy is required: Cloudflare ties the cookie to "the specific visitor and device it was issued
to", so it must be earned from the address that will use it. The whole flow in Python, with every
field a real integration sends:

```python
"""Pass a Cloudflare 5-second (JS or managed) challenge, then fetch the page with the clearance."""
import os
import sys
import time
import uuid

import requests

API = os.environ.get("ZEROCAPTCHA_API", "https://api.zerocaptcha.io")
KEY = os.environ.get("ZEROCAPTCHA_KEY") or sys.exit("Set ZEROCAPTCHA_KEY to your API key, zc_live_...")
PROXY = os.environ.get("PROXY_URL") or sys.exit("Set PROXY_URL, such as http://user:pass@proxy.example.net:8080")
PAGE = "https://shop.example.com/"
headers = {"Authorization": f"Bearer {KEY}"}

# 1. Create the task: the page behind the challenge, your proxy, where to POST the result when the
#    task ends, and an Idempotency-Key, so a retried request returns the same task instead of a
#    second, paid one. A challenge page has no sitekey, so the task takes no websiteKey.
created = requests.post(
    f"{API}/v1/tasks",
    headers={**headers, "Idempotency-Key": str(uuid.uuid4())},
    json={
        "type": "CloudflareChallengeTask",
        "websiteURL": PAGE,
        "proxy": PROXY,
        "callbackUrl": "https://example.com/zerocaptcha/callback",
    },
    timeout=15,
)
created.raise_for_status()
task = created.json()

# 2. Read it every 2 seconds until it ends.
while task["status"] in ("queued", "running"):
    time.sleep(2)
    task = requests.get(f"{API}/v1/tasks/{task['id']}", headers=headers, timeout=15).json()
if not task.get("solution"):
    sys.exit(f"{task['errorCode']}: {task['errorDescription']}")

# 3. Fetch the page through the same proxy, with the cookie and exactly its user agent.
with requests.Session() as session:
    session.proxies = {"http": PROXY, "https": PROXY}
    session.headers["User-Agent"] = task["solution"]["userAgent"]
    session.cookies.set("cf_clearance", task["solution"]["cookie"]["value"], domain="shop.example.com")
    page = session.get(PAGE, timeout=30)
    print(page.status_code, page.headers.get("cf-mitigated", "not challenged"))
```

Reuse the session for every request until the site challenges you again: the clearance lasts the
site's Challenge Passage time, 30 minutes by default, and the API serves it for 30 minutes after it
is issued. A task is charged only when it succeeds, at the price on the [pricing page](https://zerocaptcha.io/pricing);
there is no free tier or trial. If the page loads with a valid cookie and still challenges you, the
client's TLS handshake may not match the browser its user agent names: see [the challenge
loop](https://zerocaptcha.io/blog/cloudflare-challenge-loop).

The same request in curl, Node, Go and PHP is in the [Cloudflare WAF and 5-second challenges
docs](https://zerocaptcha.io/docs/challenges), and the [Cloudflare WAF and 5-second challenge
solver](https://zerocaptcha.io/cloudflare-challenge-solver) page has a sample that runs as copied against our own test
page. To see the current form of the challenge for yourself, open the [Cloudflare 5-second JS
challenge test page](https://zerocaptcha.io/captcha-test/cloudflare-js-challenge).

## Sources

- [Cloudflare challenges: challenge types and challenge pages](https://developers.cloudflare.com/cloudflare-challenges/challenge-types/challenge-pages/) (checked 1 October 2026)
- [Cloudflare: Rules language actions](https://developers.cloudflare.com/ruleset-engine/rules-language/actions/), for the API values (checked 1 October 2026)
- [Cloudflare: Under Attack mode](https://developers.cloudflare.com/fundamentals/reference/under-attack-mode/) (checked 1 October 2026)
- [Cloudflare challenges: detect a challenge response](https://developers.cloudflare.com/cloudflare-challenges/challenge-types/challenge-pages/detect-response/) (checked 1 October 2026)
- [Cloudflare: Clearance](https://developers.cloudflare.com/cloudflare-challenges/concepts/clearance/) and [Challenge Passage](https://developers.cloudflare.com/cloudflare-challenges/challenge-types/challenge-pages/challenge-passage/) (checked 1 October 2026)
- [Cloudflare challenges: supported browsers](https://developers.cloudflare.com/cloudflare-challenges/reference/supported-browsers/), on browser automation frameworks (checked 1 October 2026)
- [ZeroCaptcha: Cloudflare WAF and 5-second challenges](https://zerocaptcha.io/docs/challenges), for the task's fields and the proxy rule

## Questions

### What is the Cloudflare 5-second challenge?

The old name for Cloudflare's JavaScript challenge: an interstitial page that checked the browser for a few seconds, then let it through with a cf_clearance cookie. Today a WAF rule shows a Managed or Non-Interactive Challenge in its place, and Under Attack mode a Managed Challenge.

### Does waiting five seconds get past the challenge?

No. The page is not a timer: it runs Cloudflare's checks in the browser and posts the result back. A client that runs no JavaScript gets the same page however long it waits.

### How do I pass the Cloudflare 5-second challenge in Python?

Earn a cf_clearance cookie once, in a browser or with a challenge task through your own proxy, then send it with exactly the user agent it was issued for, through the same proxy, on every request until the site challenges you again.
