Cloudflare blocks stock headless Chrome because it announces automation (navigator.webdriver is true, and Playwright's default headless shell says HeadlessChrome in its user agent), often runs from a cloud server IP, and starts every run with no cookies. Fix it by getting recognized (an official API, or a bot verified with Web Bot Auth), or, on sites you're allowed to automate, by using a real Chromium with residential IPs and a persistent profile, which in practice means a managed stealth browser.
We make Browser Use, one of those managed browsers. Vendor facts link their own docs, checked October 27, 2026.
Why headless gets blocked
On zones with Bot Management, Cloudflare scores requests from 1 (automated) to 99 (human), and sites block or challenge low scores (bot scores). DataDome and Akamai check similar signals.
| Signal | Fix | Why stock headless fails |
|---|---|---|
| Automation tells in JavaScript | A browser that doesn't expose them. Patching them in page JS can itself be detected (see stealth plugins below) | navigator.webdriver is true under --headless or --enable-automation (MDN). Playwright's headless shell sent HeadlessChrome/153 in its user agent (our check, October 27, 2026). Checked by Cloudflare JavaScript Detections ("identifies headless browsers") and DataDome's JS tag |
| TLS and header fingerprint | Send requests from the real browser, with its own user agent | Handshake or header order that doesn't match the claimed browser. Hits HTTP clients and copied user agents. Cloudflare JA3/JA4 (Enterprise), Akamai header order and version mismatches |
| IP reputation | Residential IPs. Not enough alone | Scripts run from cloud servers or shared proxies. Cloudflare managed lists flag open proxies, anonymizers and VPNs (Enterprise) |
| Cookies and challenges | Keep a persistent profile. Detect challenges by the cf-mitigated: challenge header | A fresh context per run drops cf_clearance (stores the JS Detections result) and __cf_bm (smooths the score), so every run is judged as a new visitor. Turnstile adds proof-of-work and web API probes |
| Behavior | Pace requests, rate-limit per domain | Instant actions and request bursts. Akamai behavioral detection on login and checkout (Premier); DataDome's JS tag collects mouse movements and keystrokes |
| Identity | Sign requests and apply for verification | Anonymous automation is scored like any unknown client. Cloudflare verified bots identify by Web Bot Auth signature, published IPs or reverse DNS, and must obey robots.txt |
See what your browser leaks: open the Bot Detection Test from your automated session.
Your options
| Option | Fixes | Tradeoffs | Cost |
|---|---|---|---|
| Stealth plugins (puppeteer-extra-plugin-stealth, playwright-stealth) | JS tells such as navigator.webdriver | Don't change TLS or IP. DataDome names Puppeteer Extra Stealth as detected. The Puppeteer plugin's last release is 2.11.2, March 1, 2023 (npm); playwright-stealth 2.0.3 shipped April 4, 2026 (PyPI) | Free |
| Managed stealth browser (Browser Use Cloud, Browserbase Verified, others) | Fingerprint, residential IP, CAPTCHAs (our docs) | Paid. No vendor guarantees access; our docs say "Access to every site is not guaranteed". You still arrive unidentified | Ours: $0.02 per browser-hour plus $5/GB proxy (pricing). Browserbase Verified is on its Scale plan |
| Residential proxies alone | IP reputation | Change the IP, not the JS, cookie or TLS signals above | Per GB |
| Verified, signed bot (Web Bot Auth) | Identity: recognized, not disguised | Needs Cloudflare's approval, robots.txt and reasonable rates. Only on sites behind vendors that verify it; the site still decides to allow, challenge or block. Browserbase offers it in beta | Key hosting and a review |
| Official API, or ask the site owner | Everything: nothing to get past | May not exist or may cost money. A Cloudflare customer can let you through with a skip rule | Varies |
Pass rates: headless Chrome vs stealth browsers
Stealth Bench V2, September 25, 2026. The 100 sites were picked because our browser historically got through and stock Chrome with a US proxy did not, so the set favors us and the baselines are low by construction.
| Browser | Visits that got through |
|---|---|
| Headless Chrome, no proxy | 3% |
| Headful Chrome + US proxy | 14% |
| Six other cloud browser providers | 73.5% to 82% |
| Browser Use Cloud, CAPTCHA solver off | 84% |
| Browser Use Cloud | 90.5% |
2 visits per site; a visit counts if a judge model saw the real site within 60 seconds. Every row and site: /benchmarks/browsers; code: GitHub. In our March 2026 run on 71 sites from a datacenter IP, headless Chromium got through 2% of the time and the same Chromium with a visible window 50% (Stealth Benchmark).
Keep your Playwright script
Create a cloud browser, then replace launch() with a CDP connection (docs):
# BROWSER_USE_CDP_URL is the cdpUrl from
# POST https://api.browser-use.com/api/v4/browsers
import os
from playwright.sync_api import sync_playwright
with sync_playwright() as p:
# was: browser = p.chromium.launch()
browser = p.chromium.connect_over_cdp(os.environ["BROWSER_USE_CDP_URL"])
page = browser.contexts[0].pages[0]
page.goto("https://example.com")
# Closing CDP doesn't stop the cloud browser. When done:
# PATCH https://api.browser-use.com/api/v4/browsers/{id} {"action": "stop"}Use this only where you are allowed: follow each site's terms and robots.txt, and prefer an official API when one exists.

