← All articles

How Cloudflare bot management decides to block you

4 min read detectionanti-botcloudflare

You hit a Cloudflare challenge page, switch to a cleaner browser setup, and the block does not move. That happens because most of what Cloudflare uses to stop automated traffic is decided before your browser fingerprint is ever read.

Cloudflare sits in front of a very large share of the web, which makes it the wall most people actually hit, more often than DataDome or Kasada. It is not one gate. It is a stack of checks, and the order matters, because early layers can end the request before later ones ever run.

Four checks before your page loads

IP and ASN reputation. Every request arrives from an address with a history: a known datacenter range, a VPN or proxy provider, or a residential IP that has recently been abusive on other Cloudflare-protected sites. Cloudflare's network sees traffic across millions of domains, so this reputation is shared across sites you have never visited. This check runs before a single byte of your page is served.

TLS and HTTP/2 fingerprinting. Cloudflare hashes the TLS client hello the same way JA3 and JA4 do: cipher suite order, extensions, elliptic curves. HTTP/2 adds frame settings and header order on top. This happens at the edge, during the TLS handshake and the first HTTP frames, before the request is routed to an origin server or a page loads. A request that claims to be Chrome in its User-Agent header but negotiates TLS like a Python script gets flagged here, in milliseconds, with no JavaScript involved.

The managed challenge and Turnstile. If the first two layers are inconclusive, Cloudflare serves an interstitial, either the older "checking your browser" managed challenge or a Turnstile widget. These run small proof-of-work and environment checks in the browser (webdriver flags, timing, whether canvas and WebGL behave like real hardware) and resolve automatically for most real browsers with no user interaction.

Behavioural signals. Mouse movement, request timing and session history feed a running bot score that Cloudflare keeps updating, independent of whether a challenge was ever shown.

Hard block, managed challenge, or silent score

These are three different outcomes and worth telling apart, because the fix differs for each.

A hard block is a 403 or a challenge that never resolves, configured explicitly by the site owner for a given score threshold, country or ASN. Changing headers or fingerprints will not get you past it, because the rule is the block.

A managed challenge is the interstitial itself. It resolves automatically for a normal browser on a normal connection, and fails or loops when the environment underneath it looks synthetic: missing browser APIs, a headless tell, TLS that does not match the claimed browser.

A silent score is the most common and least visible. No interstitial, no block, but the site owner sees a bot score attached to your session in their dashboard and may quietly rate-limit, serve degraded content, or flag the account behind the scenes. The page looks like it worked. The downstream decision, a price not shown, a form that silently drops, a listing that never appears in search, happened against that score, not in front of you.

Why a better browser sometimes changes nothing

This is the part people get wrong most often. If a request is blocked on IP reputation or on the TLS handshake, it never reaches the layer where a browser's fingerprint would matter. Swapping in a more convincing user agent, patching navigator.webdriver, or running any antidetect browser with a coherent persona fixes nothing in that case, because the block already happened one or two layers earlier.

That is also why the same challenge can appear on a script and on an unmodified, real browser used through a bad proxy. The browser is not the variable that layer is checking.

Where a free approach is the better answer

If you only need to confirm whether your traffic clears the TLS layer, you do not need an antidetect browser to test that. A plain Playwright or Puppeteer launch, run through any proxy, already negotiates real Chrome TLS, because it is real Chrome. The handshake mismatch mainly shows up in raw HTTP clients such as requests, axios, or hand-rolled fetch calls with spoofed headers, and for those, free tools like curl-impersonate exist specifically to match a browser's TLS signature.

Similarly, if your Cloudflare blocks are consistently IP-based, a challenge before any script runs, on every browser you try, the fix is proxy quality, not tooling. No browser vendor, ourselves included, sells you out of a burnt IP range.

Check which layer you are hitting

Before assuming it is a fingerprint problem, look at when the block appears. A 403 or challenge before the page paints anything is network or TLS. A challenge that loads and then fails is the browser environment. A page that loads fine but results look throttled is the silent score.

Our post on TLS fingerprinting, JA3 and JA4 covers the handshake layer in detail, and how anti-bot systems decide you are a bot walks through the full stack these checks sit inside, not only Cloudflare's version of it.

Try it on the free tier.

Unlimited local profiles, no credit card. Check it against the detectors yourself.