     [Blog](https://scrapfly.io/blog)   /  [blocking](https://scrapfly.io/blog/tag/blocking)   /  [How Cloudflare Detects Bots: TLS, HTTP/2, Canvas, and Turnstile Explained](https://scrapfly.io/blog/posts/how-cloudflare-detects-bots)   # How Cloudflare Detects Bots: TLS, HTTP/2, Canvas, and Turnstile Explained

 by [Hisham Medhat](https://scrapfly.io/blog/author/hisham) Jun 25, 2026 20 min read [\#blocking](https://scrapfly.io/blog/tag/blocking) [\#python](https://scrapfly.io/blog/tag/python) 

 [  ](https://www.linkedin.com/sharing/share-offsite/?url=https%3A%2F%2Fscrapfly.io%2Fblog%2Fposts%2Fhow-cloudflare-detects-bots "Share on LinkedIn")    

 

 

         

Most Cloudflare bypass guides focus on a single trick. Swap your User-Agent, rotate proxies, or patch one JavaScript check. But Cloudflare doesn't rely on one detection method. Cloudflare stacks 7+ detection layers that run on every request. That's why single-trick approaches fail so often.

TLS fingerprinting, HTTP/2 analysis, Canvas rendering, WebGL checks, behavioral tracking, automation marker detection, and Turnstile challenges all feed into a single trust score. One mismatch lowers that score, and enough failures trigger a block.

In this guide, you'll learn how each detection layer works under the hood, why Cloudflare combines passive and active methods, and why understanding every layer is essential before you attempt any bypass. We'll cover TLS fingerprinting (JA3 and JA4), HTTP/2 fingerprinting, Canvas and WebGL browser fingerprinting, JavaScript challenges, behavioral analysis, and Turnstile.

[How to Bypass Cloudflare When Web Scraping in 2026Cloudflare offers one of the most popular anti scraping service, so in this article we'll take a look how it works and how to bypass it.](https://scrapfly.io/blog/posts/how-to-bypass-cloudflare-anti-scraping)

## Key Takeaways

Understand Cloudflare's complete bot detection pipeline so you can diagnose exactly why a scraper gets blocked before choosing how to fix it.

- Cloudflare uses passive (server-side) and active (client-side) detection methods that combine into a trust score
- TLS fingerprinting through JA3 and JA4 identifies your HTTP client before any page content loads
- HTTP/2 fingerprinting checks SETTINGS frame parameters that most scraping libraries can't spoof
- Canvas and WebGL fingerprinting creates device-class identifiers that Cloudflare cross-validates against your reported User-Agent and OS
- JavaScript challenges and Managed Challenges require real browser execution to solve
- Behavioral analysis detects automation through missing mouse movements, keyboard events, and timing anomalies
- Cloudflare Turnstile combines multiple signals into a single pass/fail challenge that replaces traditional CAPTCHAs
- Single-layer evasion fails because Cloudflare scores all signals together, so understanding what each layer measures is the first step to scraping a protected site. This article explains the detection side; our [Cloudflare bypass guide](https://scrapfly.io/blog/posts/how-to-bypass-cloudflare-anti-scraping) covers the practical fixes

**Get web scraping tips in your inbox**Trusted by 100K+ developers and 30K+ enterprises. Unsubscribe anytime.





## How Cloudflare Detects Bots

Cloudflare's bot detection pipeline splits into two categories: passive methods that run server-side before your browser receives any content, and active methods that execute client-side through JavaScript after the page loads.

**Passive detection methods** analyze your connection before the page renders. These methods include:

- **TLS fingerprinting** (JA3 and JA4) identifies your HTTP client from the TLS handshake
- **HTTP/2 fingerprinting** checks SETTINGS frame parameters and priority signals
- **IP reputation** scores your IP address based on datacenter vs. residential classification and abuse history
- **HTTP header analysis** compares header order, values, and consistency against known browser profiles

**Active detection methods** require JavaScript execution on the client side. These methods include:

- **Canvas and WebGL fingerprinting** renders hidden elements to identify your GPU and device class
- **JavaScript challenges** run browser tests and report results back to Cloudflare
- **Behavioral analysis** tracks mouse movements, keystrokes, scroll events, and timing patterns
- **Automation marker detection** checks for WebDriver flags, Selenium artifacts, and sandbox indicators
- **Turnstile** combines multiple signals into a non-interactive or interactive challenge

The important point is that Cloudflare uses a **trust score** that combines ALL of these signals. Failing one layer doesn't necessarily block your request, but each failure lowers the score. When the score drops below a threshold, Cloudflare serves a challenge page or blocks the request entirely. That's why addressing just one layer, like TLS fingerprinting, still results in blocks if your browser fingerprint or behavioral patterns look automated.

Now let's examine each detection layer in detail, starting with the first check your request encounters.

[How to Know What Anti-Bot Service a Website is Using?In this article we'll take a look at two popular tools: WhatWaf and Wafw00f which can identify what WAF service is used.](https://scrapfly.io/blog/posts/how-to-know-what-anti-bot-website-uses)

## TLS Fingerprinting (JA3 and JA4)

Every HTTPS connection starts with a TLS handshake. Before any encrypted data flows, the client sends a **ClientHello** message in cleartext. The ClientHello contains the TLS version, supported cipher suites, TLS extensions, elliptic curves, and point formats. Since different HTTP clients (Chrome, Firefox, Python's `requests`, Go's `net/http`) support different cipher suites and extensions, the ClientHello message is unique to each client.

### How JA3 Fingerprinting Works

JA3 fingerprinting extracts five fields from the ClientHello message and hashes the values into an MD5 string:

- **TLS version** (e.g., TLS 1.2 = 771, TLS 1.3 = 772)
- **Cipher suites** (ordered list of supported encryption algorithms)
- **Extensions** (ordered list of TLS extensions)
- **Elliptic curves** (supported curve groups)
- **Point formats** (elliptic curve point format types)

These five fields get concatenated with commas and hashed into a 32-character MD5 fingerprint. Python's `requests` library produces a JA3 hash that looks nothing like Chrome's because `requests` uses Python's `ssl` module with different cipher suites and extension ordering. Cloudflare maintains a database of known browser JA3 hashes. When your request arrives with a JA3 that matches Python's `requests` instead of Chrome, Cloudflare immediately flags the connection as non-browser traffic.

You can check your JA3 fingerprint using [Scrapfly's JA3 fingerprint tool](https://scrapfly.io/web-scraping-tools/ja3-fingerprint).

### How JA4 Fingerprinting Works

Modern browsers randomize TLS extension ordering to break JA3. Chrome and Firefox shuffle extensions on every connection, making JA3 hashes inconsistent across requests from the same browser. JA4 solves this problem.

JA4 normalizes the extension list by sorting extensions alphabetically before hashing, so randomized ordering produces the same fingerprint. JA4 also adds context that JA3 ignores:

- **Protocol type** (TCP or QUIC)
- **TLS version** as a human-readable prefix
- **ALPN value** (h2 for HTTP/2, h1 for HTTP/1.1)
- **Cipher suite count and extension count** in the first section

The result is a 36-character identifier in an `a_b_c` format. The first section (`a`) contains metadata like protocol, TLS version, and counts. The second section (`b`) is a hash of the sorted cipher suites. The third section (`c`) is a hash of the sorted extensions plus signature algorithms.

JA4's format makes fingerprints both **human-readable and machine-comparable**. You can tell at a glance whether a fingerprint uses TLS 1.3 over TCP with HTTP/2, without decoding a hash. JA4 also includes variants like JA4S (server fingerprint), JA4H (HTTP client fingerprint), and JA4X (X.509 certificate fingerprint).

Cloudflare adopted JA4 alongside JA3 in its bot detection pipeline. You can test your JA4 fingerprint with [Scrapfly's JA4 fingerprint tester](https://scrapfly.io/web-scraping-tools/ja4-fingerprint).

### Why TLS Fingerprinting Matters for Scraping

Python's `requests` library, Go's `net/http`, and most scraping-focused HTTP clients produce TLS fingerprints that differ from any real browser. Cloudflare compares your JA3/JA4 against a database of known browser fingerprints. A mismatch lowers your trust score before the page even starts loading.

Tools like `curl_cffi` and curl-impersonate let a Python client present a real Chrome TLS profile instead of the default Python signature that Cloudflare immediately flags as non-browser. For the implementation and working code, see our [guide to TLS fingerprinting in web scraping](https://scrapfly.io/blog/posts/how-to-avoid-web-scraping-blocking-tls).

[Use Curl Impersonate to scrape as Chrome or FirefoxLearn how to prevent TLS fingerprinting by impersonating normal web browser configurations. We'll start by explaining what the Curl Impersonate is, how it works, how to install and use it. Finally, we'll explore using it with Python to avoid web scraping blocking.](https://scrapfly.io/blog/posts/curl-impersonate-scrape-chrome-firefox-tls-http2-fingerprint)

## HTTP/2 Fingerprinting

TLS fingerprinting identifies the TLS library your client uses. HTTP/2 fingerprinting goes one step further by identifying the HTTP client itself. Every HTTP/2 connection starts with a **SETTINGS frame** that contains parameters specific to the client implementation.

### What Gets Fingerprinted

The HTTP/2 SETTINGS frame includes parameters that vary across HTTP clients:

- **HEADER\_TABLE\_SIZE** controls the HPACK header compression table size
- **ENABLE\_PUSH** indicates whether server push is supported
- **MAX\_CONCURRENT\_STREAMS** sets the maximum number of simultaneous streams
- **INITIAL\_WINDOW\_SIZE** defines the flow control window size
- **MAX\_FRAME\_SIZE** sets the maximum frame payload size
- **MAX\_HEADER\_LIST\_SIZE** limits the total size of header blocks

Beyond the SETTINGS frame, HTTP/2 fingerprinting also captures **WINDOW\_UPDATE** values and **pseudo-header ordering** (`:method`, `:authority`, `:scheme`, `:path`).

The differences between clients are large. Chrome sets INITIAL\_WINDOW\_SIZE to 6,291,456 bytes. Go's `net/http` uses the default 65,535 bytes. That's a 100x difference in a single parameter. Python's `httpx` and `aiohttp` also have default HTTP/2 parameters that differ from any browser.

### How Cloudflare Uses HTTP/2 Fingerprints

Cloudflare checks that your HTTP/2 fingerprint, TLS fingerprint, and User-Agent header tell a consistent story. Sending a Chrome User-Agent with Python's `httpx` HTTP/2 parameters creates a mismatch that Cloudflare detects as a strong bot signal.

Most HTTP libraries don't expose HTTP/2 frame-level settings to developers. You can't easily change `httpx`'s INITIAL\_WINDOW\_SIZE to match Chrome's value. This makes HTTP/2 fingerprinting harder to spoof than TLS fingerprinting, where libraries like curl\_cffi provide explicit impersonation options.

The combination of TLS and HTTP/2 fingerprinting creates a two-layer identification system. Even if you spoof the TLS fingerprint perfectly, a mismatched HTTP/2 fingerprint reveals the actual client. Tools that handle both layers, like fortified headless browsers and curl\_cffi, are necessary for consistent bypasses.

With the server-side fingerprinting layers covered, let's move to the client-side detection methods that run after the page loads.

## Browser Fingerprinting (Canvas and WebGL)

Once your request passes TLS and HTTP/2 checks, Cloudflare's JavaScript challenges run client-side browser fingerprinting. Canvas and WebGL fingerprinting are two of the most effective active detection methods because they identify the physical hardware behind the browser.

### Canvas Fingerprinting

Canvas fingerprinting uses the HTML5 Canvas API to render a hidden image on the page. The JavaScript draws text and shapes using specific fonts, colors, and rendering instructions. The rendered result gets converted to a pixel array and hashed into a unique identifier.

The important point is that the same Canvas drawing instructions produce slightly different pixel output on different hardware. The differences come from:

- **GPU model and driver version** affect anti-aliasing and sub-pixel rendering
- **Operating system** controls font rendering (ClearType on Windows, Core Text on macOS)
- **Browser rendering engine** (Blink in Chrome vs. Gecko in Firefox) processes drawing instructions differently
- **Display scaling** affects pixel density and rounding

Cloudflare collects Canvas fingerprints and cross-validates against your reported User-Agent and operating system. A Canvas fingerprint from a Windows machine paired with a macOS User-Agent is an obvious inconsistency. Cloudflare also maintains ML models that detect **tampered Canvas fingerprints**. Random values or static fingerprints stand out because they don't match any real hardware profile.

You can check your Canvas fingerprint using [Scrapfly's Canvas fingerprint tool](https://scrapfly.io/web-scraping-tools/canvas-fingerprint).

### WebGL Fingerprinting

WebGL fingerprinting works similarly to Canvas but uses the WebGL API for 3D rendering. WebGL exposes more hardware details than Canvas:

- **GPU vendor string** (e.g., "NVIDIA Corporation", "Intel Inc.")
- **GPU renderer string** (e.g., "NVIDIA GeForce RTX 4090", "Intel Iris Plus Graphics")
- **Supported WebGL extensions** (list of available rendering features)
- **Shader precision formats** (floating-point precision varies by GPU)
- **Maximum texture size and viewport dimensions**

Cloudflare combines Canvas and WebGL fingerprints into a **device class identifier**. The device class groups users by hardware profile. A headless Chrome instance running on a Linux server without a real GPU produces a WebGL fingerprint that identifies software rendering (e.g., "SwiftShader" or "llvmpipe"). Real browsers on consumer hardware report actual GPU models.

### Why Spoofing Browser Fingerprints Is Difficult

Spoofing Canvas or WebGL fingerprints alone isn't enough. The fingerprint must be **internally consistent** with your reported browser, OS, GPU, and screen resolution. Claiming a Chrome User-Agent on Windows 11 while producing a Canvas fingerprint from an Intel GPU on macOS triggers Cloudflare's inconsistency detection.

Anti-detect browsers like Camoufox handle Canvas and WebGL fingerprinting by generating consistent fingerprint profiles that match real hardware configurations. Simple JavaScript injection to override `HTMLCanvasElement.prototype.toDataURL` is detectable because Cloudflare checks whether prototype methods have been tampered with.

For more on browser fingerprinting techniques, see our guide on [browser fingerprinting with CreepJS](https://scrapfly.io/blog/posts/browser-fingerprinting-with-creepjs).

## JavaScript Challenges and Managed Challenges

When you see Cloudflare's "Checking your browser..." page, you're facing a JavaScript challenge. The page isn't just a loading screen. Cloudflare serves JavaScript that runs dozens of client-side tests, collects browser signals, and reports the results back to Cloudflare's servers.

### What Happens During a JavaScript Challenge

The challenge JavaScript executes a sequence of tests on the client:

1. **Browser environment checks** verify that standard Web APIs exist and behave correctly (e.g., `document.createElement`, `window.setTimeout`, `navigator` properties)
2. **Fingerprint collection** runs Canvas, WebGL, and other fingerprinting tests to build a device profile
3. **Timing validation** measures execution timing to detect sandboxed or emulated environments
4. **Event handler installation** sets up listeners for mouse, keyboard, and touch events
5. **Proof-of-work computation** solves a computational puzzle that requires real CPU time
6. **Result encryption and submission** packages all collected data, encrypts the payload, and sends the results to Cloudflare

Cloudflare's server validates the submitted data against expected values. If the results pass, the server issues a `cf_clearance` cookie that grants access to the protected site. If the results fail, Cloudflare either presents a Turnstile challenge or blocks the request.

### Managed Challenges

Managed Challenges replaced Cloudflare's older "I'm Under Attack" mode. Instead of always showing a CAPTCHA, Cloudflare dynamically chooses the challenge type based on your trust score:

- **Non-interactive pass-through** for high-trust requests (clean IP, matching fingerprints, no anomalies)
- **Non-interactive JavaScript challenge** for medium-trust requests (the "Checking your browser" page)
- **Interactive Turnstile challenge** for low-trust requests (checkbox or behavioral challenge)
- **Block** for very low-trust requests (known bad actors, impossible fingerprints)

### Why Simple HTTP Requests Fail

Plain HTTP clients like `requests` or `httpx` can't solve JavaScript challenges because they don't have a JavaScript engine. No JavaScript execution means no challenge solution, which means no `cf_clearance` cookie. This is why headless browsers are necessary for scraping many Cloudflare-protected sites.

Even headless browsers need stealth patches to pass the JavaScript challenge. Default Selenium or [Playwright](https://scrapfly.io/blog/posts/web-scraping-with-playwright-and-python) configurations expose automation markers that the challenge JavaScript detects during its browser environment checks.

## Behavioral Analysis and Automation Detection

Cloudflare's behavioral layer catches bots that pass all fingerprinting checks. Even with a perfect TLS fingerprint, valid Canvas hash, and correct HTTP/2 parameters, missing behavioral signals reveal automation.

### Event Listening

Cloudflare injects JavaScript that registers `addEventListener` callbacks for multiple event types:

- **Mouse events**: `mousemove`, `mousedown`, `mouseup`, `click`
- **Keyboard events**: `keydown`, `keyup`, `keypress`
- **Touch events**: `touchstart`, `touchmove`, `touchend`
- **Scroll events**: `scroll`, `wheel`

Real users generate hundreds of mouse movement events when navigating a page. A request that loads a page with zero mouse or keyboard events within the first few seconds is suspicious. Cloudflare doesn't require specific interaction patterns, but the complete absence of events is a strong bot signal.

### Timestamp and Timing Analysis

Cloudflare uses multiple timing APIs to detect non-human interaction patterns:

- **`performance.now()`** measures high-resolution timestamps between events
- **`Date.now()`** tracks wall-clock timing of page interactions
- **`requestAnimationFrame`** checks rendering frame timing

A page that loads and immediately submits a form with zero time between events doesn't match human behavior. Cloudflare's timing checks also detect environments where `performance.now()` returns manipulated values or where timestamps don't correlate with actual elapsed time.

### Automation Marker Detection

Cloudflare's JavaScript checks for known automation artifacts in the browser environment:

- **`navigator.webdriver`** returns `true` in automated browsers (Selenium, Playwright)
- **`window.document.__selenium_unwrapped`** and **`window.__selenium_evaluate`** are Selenium-specific globals
- **`window.callPhantom`** and **`window._phantom`** indicate PhantomJS
- **`window.__nightmare`** indicates Nightmare.js
- **Modified `Function.prototype.toString`** reveals when native functions have been overridden by automation scripts

### Sandbox Detection

Beyond browser automation, Cloudflare also detects non-browser JavaScript environments:

- **`process` and `global` objects** indicate Node.js execution
- **JSDOM artifacts** reveal server-side DOM emulation
- **Missing Web APIs** that should exist in real browsers (e.g., `Worker`, `ServiceWorker`, `WebAssembly`)

These checks prevent developers from using lightweight JavaScript runtimes to solve challenges without running a full browser. Stealth plugins for headless browsers (Camoufox, Nodriver, SeleniumBase UC Mode) exist specifically to remove these automation markers and inject human-like behavioral signals.

For more tools that help avoid detection, see our guide on [scraping without getting blocked](https://scrapfly.io/blog/posts/how-to-scrape-without-getting-blocked-tutorial).

[The Complete Guide To Using Proxies For Web ScrapingIntroduction to proxy usage in web scraping. What types of proxies are there? How to evaluate proxy providers and avoid common issues.](https://scrapfly.io/blog/posts/introduction-to-proxies-in-web-scraping)

## Cloudflare Turnstile

Cloudflare Turnstile is a smart CAPTCHA replacement that runs invisible or minimal-interaction challenges. Unlike traditional image-based CAPTCHAs, Turnstile doesn't ask users to identify traffic lights or crosswalks. Instead, Turnstile uses background signals to determine whether a visitor is human.

### How Turnstile Works

Turnstile generates a token through a multi-step process:

1. **Background signal collection** gathers browser fingerprints, behavioral data, and environment checks
2. **Proof-of-work challenge** requires the browser to solve a computational puzzle
3. **Signal validation** compares collected data against expected values for the reported browser and device
4. **Token generation** produces a cryptographic token if all checks pass
5. **Server-side verification** validates the token through Cloudflare's API when the form submits

The generated token is tied to the specific browser session and expires after a set period. Server-side code validates the token by sending the token to Cloudflare's `/siteverify` endpoint. Without a valid token, the server rejects the request.

### Turnstile Modes

Turnstile runs in three modes: **managed** (Cloudflare automatically picks the challenge based on trust score, and most visitors pass without seeing anything), **non-interactive** (runs entirely in the background with no visible widget), and **interactive** (shows a checkbox to low-trust visitors). Non-interactive mode is the most common and the hardest for scrapers, because the token is generated purely from background signals and proof-of-work. There is no visual puzzle for a CAPTCHA-solving service to solve, so the only way through is to produce the signals a real browser would.

### Why Turnstile Is the Hardest Layer

Turnstile combines multiple detection signals into a single pass/fail decision. The challenge verifies browser fingerprints, behavioral patterns, JavaScript environment integrity, and proof-of-work results simultaneously. You can't bypass Turnstile by handling just one signal. Every check must pass for the token to generate.

Turnstile also works outside of Cloudflare's CDN. Website owners can embed Turnstile on any site, regardless of whether the site uses Cloudflare's proxy. This makes Turnstile a standalone challenge that can protect login forms, checkout pages, and API endpoints independently.

For strategies on handling CAPTCHAs and Turnstile, see our guides on [bypassing Cloudflare Turnstile](https://scrapfly.io/blog/posts/how-to-bypass-cloudflare-turnstile), [CAPTCHA bypass strategies](https://scrapfly.io/blog/posts/how-to-bypass-captcha-while-web-scraping), and [CAPTCHA solving services](https://scrapfly.io/blog/posts/best-captcha-solving-api).

Now that you understand every detection layer, the practical question is how to satisfy all of them at once.

## How to Scrape Cloudflare-Protected Sites

Because the trust score combines every signal, a single-layer fix is never enough. Spoofing your TLS fingerprint does nothing if your HTTP/2 parameters, browser fingerprint, and behavioral signals still look automated. A working setup has to keep every layer aligned at the same time.

In practice, that means one of three paths: a fortified headless browser (Camoufox, Nodriver, or SeleniumBase UC Mode) for sites with JavaScript challenges and Turnstile; a TLS-impersonating HTTP client like `curl_cffi` for sites with lighter protection and no JavaScript checks; or a managed scraping API that handles every layer for you. Each path trades off reliability, speed, and how much maintenance you carry.

We cover the setup, working code, and trade-offs for all three approaches in our dedicated [guide to bypassing Cloudflare when web scraping](https://scrapfly.io/blog/posts/how-to-bypass-cloudflare-anti-scraping).



## Scraping Cloudflare with Scrapfly



Scrapfly handles all Cloudflare detection layers in a single API call. Instead of managing TLS libraries, headless browsers, proxies, and CAPTCHA solvers separately, Scrapfly's Anti-Scraping Protection (`asp=true`) addresses every layer automatically. Set `asp=true` and Scrapfly selects the right fingerprint profile, solves challenges, and returns the page content.

Here's how to scrape a Cloudflare-protected page with Scrapfly's Python SDK:

bash```bash
pip install scrapfly-sdk
```



python```python
from scrapfly import ScrapeConfig, ScrapflyClient

scrapfly = ScrapflyClient(key="Your Scrapfly API key")

response = scrapfly.scrape(ScrapeConfig(
    url="https://web-scraping.dev/products",
    asp=True,  # enable anti-scraping protection
    country="US",  # set proxy location
    render_js=True,  # enable JavaScript rendering
))

html = response.scrape_result["content"]
print(html[:500])
```



The code above sends a scrape request with anti-scraping protection enabled. Scrapfly automatically handles TLS fingerprint matching, HTTP/2 parameter spoofing, browser fingerprint generation, JavaScript challenge solving, and proxy rotation. The `render_js=True` parameter enables a headless browser for pages that require JavaScript execution. For static pages behind lighter Cloudflare protection, you can omit `render_js` to get faster responses.

Scrapfly supports scraping Cloudflare-protected sites at scale without managing infrastructure. Instead of maintaining headless browser pools, proxy lists, and fingerprint configurations, a single API call handles the entire bypass pipeline.



## FAQ

Does Cloudflare prevent bots?Yes. Cloudflare uses a multi-layered detection system that combines passive methods (TLS and HTTP/2 fingerprinting, IP reputation) with active methods (Canvas and WebGL fingerprinting, JavaScript challenges, behavioral analysis, Turnstile). All signals feed into a trust score that determines whether to allow, challenge, or block the request.







What is the difference between JA3 and JA4 fingerprinting?JA3 hashes five TLS handshake fields (version, ciphers, extensions, curves, point formats) into an MD5 string. JA4 normalizes fields by sorting extensions alphabetically to resist browser randomization, adds TCP/HTTP/2 context and ALPN values, and produces a 36-character human-readable identifier. JA4 is harder to evade through extension shuffling.







How does Cloudflare's trust score work?Cloudflare does not make an allow-or-block decision from a single signal. It combines passive checks (TLS and HTTP/2 fingerprints, IP reputation, header consistency) with active checks (Canvas and WebGL fingerprints, JavaScript challenge results, behavioral signals, Turnstile) into one trust score. Failing a single layer lowers the score rather than blocking outright; once the score falls below a threshold, Cloudflare serves a challenge or blocks the request. This is why fixing only one layer still results in blocks.







Can Cloudflare detect headless browsers?Yes. Even when a headless browser passes TLS and HTTP/2 checks, Cloudflare looks for automation markers (`navigator.webdriver`, Selenium and PhantomJS globals, overridden native functions), software-rendering WebGL fingerprints (SwiftShader or llvmpipe) typical of GPU-less servers, and the absence of human behavioral signals like mouse movement. Default Selenium or Playwright is detected quickly; stealth-patched browsers remove the markers but must keep every other layer consistent to stay hidden.







What is my JA3 or JA4 fingerprint?Use [Scrapfly's JA3 fingerprint tool](https://scrapfly.io/web-scraping-tools/ja3-fingerprint) or [JA4 fingerprint tester](https://scrapfly.io/web-scraping-tools/ja4-fingerprint) to check your TLS fingerprint. You can also send a request to `https://tls.browserleaks.com/json` using your HTTP client to see the JA3 hash in the response.







What is HTTP/2 fingerprinting and why can't I spoof it?Every HTTP/2 client sends a SETTINGS frame whose parameters (HEADER\_TABLE\_SIZE, INITIAL\_WINDOW\_SIZE, MAX\_CONCURRENT\_STREAMS) and pseudo-header ordering differ between Chrome, Go, and Python clients. Cloudflare checks that your HTTP/2 fingerprint, TLS fingerprint, and User-Agent tell a consistent story. It is hard to spoof because most HTTP libraries do not expose frame-level settings, so you cannot simply set `httpx`'s window size to match Chrome's, unlike TLS, where libraries like curl\_cffi offer explicit impersonation.









## Summary

Cloudflare's bot detection runs 7+ layers simultaneously: TLS fingerprinting (JA3 and JA4), HTTP/2 fingerprinting, Canvas and WebGL browser fingerprinting, JavaScript and Managed Challenges, behavioral analysis, automation marker detection, and Turnstile. None of them act alone. Each feeds a single trust score, and falling short on any one signal lowers your chance of getting through, which is why fixing a single layer rarely works.

Understanding what each layer actually measures is what lets you diagnose why a scraper gets blocked instead of guessing. Once you know which signal is failing, whether it's a Python TLS fingerprint, a software-rendered WebGL hash, missing behavioral events, or an unsolved Turnstile token, you can choose the right tool to fix it. For the practical setups that satisfy all of these layers, including stealth browsers, TLS-impersonating clients, and managed APIs, see our [Cloudflare bypass guide](https://scrapfly.io/blog/posts/how-to-bypass-cloudflare-anti-scraping).

Legal Disclaimer and PrecautionsThis tutorial covers popular web scraping techniques for education. Interacting with public servers requires diligence and respect:

- Do not scrape at rates that could damage the website.
- Do not scrape data that's not available publicly.
- Do not store PII of EU citizens protected by GDPR.
- Do not repurpose *entire* public datasets which can be illegal in some countries.

Scrapfly does not offer legal advice but these are good general rules to follow. For more you should consult a lawyer.



 

   Table of Contents















 

  Table of Contents- [Key Takeaways](#key-takeaways)
- [How Cloudflare Detects Bots](#how-cloudflare-detects-bots)
- [TLS Fingerprinting (JA3 and JA4)](#tls-fingerprinting-ja3-and-ja4)
- [How JA3 Fingerprinting Works](#how-ja3-fingerprinting-works)
- [How JA4 Fingerprinting Works](#how-ja4-fingerprinting-works)
- [Why TLS Fingerprinting Matters for Scraping](#why-tls-fingerprinting-matters-for-scraping)
- [HTTP/2 Fingerprinting](#http-2-fingerprinting)
- [What Gets Fingerprinted](#what-gets-fingerprinted)
- [How Cloudflare Uses HTTP/2 Fingerprints](#how-cloudflare-uses-http-2-fingerprints)
- [Browser Fingerprinting (Canvas and WebGL)](#browser-fingerprinting-canvas-and-webgl)
- [Canvas Fingerprinting](#canvas-fingerprinting)
- [WebGL Fingerprinting](#webgl-fingerprinting)
- [Why Spoofing Browser Fingerprints Is Difficult](#why-spoofing-browser-fingerprints-is-difficult)
- [JavaScript Challenges and Managed Challenges](#javascript-challenges-and-managed-challenges)
- [What Happens During a JavaScript Challenge](#what-happens-during-a-javascript-challenge)
- [Managed Challenges](#managed-challenges)
- [Why Simple HTTP Requests Fail](#why-simple-http-requests-fail)
- [Behavioral Analysis and Automation Detection](#behavioral-analysis-and-automation-detection)
- [Event Listening](#event-listening)
- [Timestamp and Timing Analysis](#timestamp-and-timing-analysis)
- [Automation Marker Detection](#automation-marker-detection)
- [Sandbox Detection](#sandbox-detection)
- [Cloudflare Turnstile](#cloudflare-turnstile)
- [How Turnstile Works](#how-turnstile-works)
- [Turnstile Modes](#turnstile-modes)
- [Why Turnstile Is the Hardest Layer](#why-turnstile-is-the-hardest-layer)
- [How to Scrape Cloudflare-Protected Sites](#how-to-scrape-cloudflare-protected-sites)
- [Scraping Cloudflare with Scrapfly](#scraping-cloudflare-with-scrapfly)
- [FAQ](#faq)
- [Summary](#summary)
 
    Join the Newsletter  Get monthly web scraping insights 

 

  



Scale Your Web Scraping

Anti-bot bypass, browser rendering, and rotating proxies, all in one API. Start with 1,000 free credits.

  No credit card required  1,000 free API credits  Anti-bot bypass included 

 [Start Free](https://scrapfly.io/register) [View Docs](https://scrapfly.io/docs/onboarding) 

 Not ready? Get our newsletter instead. 

 

## Explore this Article with AI

 [ ChatGPT ](https://chat.openai.com/?q=Summarize%20this%20page%3A%20https%3A%2F%2Fscrapfly.io%2Fblog%2Fposts%2Fhow-cloudflare-detects-bots) [ Gemini ](https://www.google.com/search?udm=50&aep=11&q=Summarize%20this%20page%3A%20https%3A%2F%2Fscrapfly.io%2Fblog%2Fposts%2Fhow-cloudflare-detects-bots) [ Grok ](https://x.com/i/grok?text=Summarize%20this%20page%3A%20https%3A%2F%2Fscrapfly.io%2Fblog%2Fposts%2Fhow-cloudflare-detects-bots) [ Perplexity ](https://www.perplexity.ai/search/new?q=Summarize%20this%20page%3A%20https%3A%2F%2Fscrapfly.io%2Fblog%2Fposts%2Fhow-cloudflare-detects-bots) [ Claude ](https://claude.ai/new?q=Summarize%20this%20page%3A%20https%3A%2F%2Fscrapfly.io%2Fblog%2Fposts%2Fhow-cloudflare-detects-bots) 



 ## Related Articles

 [  

 blocking 

### What is CreepJS Browser Fingerprint and How to Bypass It

In this article, we will explore the inner workings of CreepJS, one of the prominent browser fingerprinting tools and ho...

 

 ](https://scrapfly.io/blog/posts/browser-fingerprinting-with-creepjs) [     

 blocking 

### How to Bypass Cloudflare Turnstile

Learn how Cloudflare Turnstile detects bots and 3 proven methods to bypass Turnstile challenges when web scraping.

 

 ](https://scrapfly.io/blog/posts/how-to-bypass-cloudflare-turnstile) [     

 blocking tools 

### How Browser Fingerprinting Works and How to Defend Against It

Learn how browser fingerprinting works, from canvas to WebGPU, and discover developer-focused techniques to bypass detec...

 

 ](https://scrapfly.io/blog/posts/how-browser-fingerprinting-works) 

  ## Related Questions

- [ Q How to check if element exists in Playwright? ](https://scrapfly.io/blog/answers/how-to-check-for-element-in-playwright)
 
  



   



 Bypass anti-bot protection automatically, **1,000 free credits** [Start Free](https://scrapfly.io/register)