How to Bypass Cloudflare with Proxies (Without Getting Blocked)
Cloudflare protects roughly 20% of all websites on the internet. If you are scraping at any meaningful scale, you will encounter Cloudflare’s bot detection sooner or later. And when you do, you will discover that the proxy type you use determines whether you succeed or fail before any other factor comes into play.
This guide breaks down exactly how Cloudflare’s bot detection works at a technical level, explains why datacenter and most residential proxies fail against it, and provides a concrete strategy for consistent access using mobile proxies combined with proper browser automation.
How Cloudflare Bot Detection Works
Cloudflare does not use a single detection method. It layers multiple signals into a composite risk score, and each layer can independently trigger a challenge or block. Understanding every layer is essential for building a bypass strategy.
Layer 1: IP Reputation and ASN Classification
Every incoming request is evaluated against Cloudflare’s threat intelligence database. This evaluation happens before any content is served.
What Cloudflare checks:
- ASN type: Is the IP from a datacenter, residential ISP, or mobile carrier? Datacenter ASNs (AWS, Azure, GCP, Hetzner, OVH) are immediately flagged as high-risk.
- IP history: Has this specific IP been associated with abusive traffic, credential stuffing, or scraping? Cloudflare processes trillions of requests monthly and maintains extensive IP histories.
- IP density: How many different websites is this IP requesting from in a short time window? Scraping bots tend to hit many different Cloudflare-protected domains, creating a distinctive pattern.
- Geographic consistency: Does the IP’s geographic location match the request patterns? An IP in Singapore requesting US English content at 3 AM Singapore time is mildly suspicious.
This is the most impactful layer. A datacenter IP starts at a severe disadvantage that no amount of browser fingerprint optimization can overcome. For a detailed comparison of how different proxy types score on IP reputation, see our proxy comparison guide.
Layer 2: JavaScript Challenge (Under Attack Mode)
When Cloudflare decides to challenge a request, it serves a JavaScript challenge page instead of the requested content. The visitor’s browser must execute the JavaScript and pass the challenge to receive a cf_clearance cookie.
What the challenge evaluates:
- Whether JavaScript actually executes (pure HTTP libraries fail here)
- Execution timing (headless browsers often solve challenges too quickly)
- Browser environment consistency (navigator properties, window dimensions, installed plugins)
- Canvas fingerprint (rendered via JavaScript and compared against known headless browser signatures)
The JavaScript challenge is designed to be invisible to real users — it completes in 1-3 seconds. But it is a hard blocker for any tool that does not execute JavaScript in a real browser environment.
Layer 3: Turnstile (CAPTCHA Replacement)
Cloudflare’s Turnstile is their replacement for traditional CAPTCHAs. Unlike reCAPTCHA, Turnstile does not require user interaction in most cases. It runs a series of background challenges:
- Proof of work: The browser performs computational work to prove it is not a cheap bot that cannot afford CPU cycles
- Environment probing: JavaScript checks for browser API consistency, screen rendering capabilities, and hardware characteristics
- Behavioral analysis: Mouse movements, scroll patterns, and timing between interactions are analyzed
- Private Access Tokens: On Apple devices, Turnstile can use Private Access Tokens (PAT) to verify the device without any challenge
Turnstile is harder to bypass than traditional CAPTCHAs because it runs passively. The user (or bot) does not know what is being tested or when.
Layer 4: Managed Challenge
The managed challenge is Cloudflare’s adaptive challenge system. It automatically selects the challenge type based on the request’s risk score:
- Low risk: No challenge, request passes through
- Medium risk: JavaScript challenge or invisible Turnstile
- High risk: Interactive Turnstile or complete block
The managed challenge adapts in real-time. If your first request passes but subsequent requests show bot-like patterns, later requests will face stricter challenges.
Layer 5: TLS Fingerprinting
This is where many scraping setups fail silently. Cloudflare analyzes the TLS Client Hello message sent during the HTTPS handshake. Every TLS library produces a distinctive fingerprint based on:
- Supported cipher suites and their order
- TLS extensions and their order
- Supported elliptic curves
- Supported point formats
- ALPN protocols
Chrome, Firefox, Safari, and curl all produce different TLS fingerprints. Headless Chrome produces a fingerprint identical to regular Chrome, which is why it is preferred for scraping. But Python’s requests library produces a fingerprint that looks nothing like any browser — it is an immediate red flag.
JA3 fingerprinting is the specific technique Cloudflare uses to hash TLS Client Hello parameters. Your TLS fingerprint must match a known browser, or your request is flagged regardless of IP quality.
Layer 6: HTTP/2 Fingerprinting
Beyond TLS, Cloudflare also analyzes HTTP/2 connection parameters:
- SETTINGS frame values (header table size, max concurrent streams, initial window size)
- WINDOW_UPDATE frame behavior
- Header order and pseudo-header order
- Priority frames
Each browser implementation has characteristic HTTP/2 settings. A mismatch between your declared User-Agent (e.g., Chrome) and your actual HTTP/2 fingerprint (e.g., Python aiohttp) is a detection signal.
Why Datacenter Proxies Fail Against Cloudflare
Datacenter proxies fail at Layer 1 — the very first check. The request arrives from an IP registered to a hosting provider, and Cloudflare’s system immediately classifies it as high-risk.
Even if you somehow pass the IP check (rare, but possible with clean datacenter IPs and low traffic volume), the subsequent layers compound the difficulty:
- IP flagged as datacenter (Layer 1 failure)
- JavaScript challenge served (Layer 2)
- If challenge is solved, TLS fingerprint is checked (Layer 5)
- If TLS is spoofed, HTTP/2 fingerprint is checked (Layer 6)
- If all pass, behavioral analysis monitors ongoing requests
Each layer independently can block you. Passing all six layers consistently with datacenter infrastructure is practically impossible at scale.
Why Residential Proxies Are Not Enough
Residential proxies pass Layer 1 better than datacenter proxies, but they face increasing challenges:
- Burned IPs: Many residential IPs in major proxy pools have been flagged by Cloudflare due to overuse. When thousands of scraping customers share the same IP pool, those IPs accumulate abuse scores.
- Connection patterns: Residential IPs used for scraping show non-residential traffic patterns — high request rates, many different target domains, no browser-like resource loading.
- Pool detection: Cloudflare has identified the IP ranges used by major residential proxy providers. Requests from these ranges face heightened scrutiny.
Residential proxies still work against Cloudflare for low-volume scraping, but success rates have been declining year over year as Cloudflare’s detection improves.
The Mobile Proxy Advantage
Mobile proxies succeed against Cloudflare because of a technical reality that Cloudflare cannot work around: CGNAT (Carrier-Grade NAT).
Why Cloudflare Cannot Block Mobile IPs
Mobile carrier IPs are shared by thousands of legitimate users simultaneously through CGNAT. If Cloudflare blocks a mobile IP, they block every real user behind that IP — potentially thousands of real humans browsing on their phones.
Cloudflare’s business model depends on protecting websites without blocking legitimate visitors. Aggressively blocking mobile carrier IPs would cause massive false positives, driving website owners away from Cloudflare. This gives mobile IPs an inherent trust advantage that no other proxy type can match.
Mobile IP Trust Scoring
In Cloudflare’s risk scoring system, mobile carrier IPs consistently score in the lowest risk tier:
- ASN classification: Mobile carrier (highest trust category)
- Historical abuse: Diluted across thousands of CGNAT users (low per-IP abuse score)
- Connection patterns: Mobile users access many different websites (normal behavior matches scraping patterns)
This does not mean mobile proxies are invisible to Cloudflare. They still face JavaScript challenges and fingerprint checks. But they start from a much stronger position, meaning the subsequent layers are less aggressive.
For a deeper explanation of why mobile proxies outperform alternatives specifically for scraping, see our mobile proxy scraping guide.
Building a Cloudflare Bypass Stack
A successful Cloudflare bypass requires addressing every detection layer. Here is the recommended stack.
Recommended Components
- Mobile proxies (addresses Layer 1: IP reputation)
- Real browser automation (addresses Layer 2: JavaScript challenges)
- Stealth plugins (addresses Layer 3/4: Turnstile and behavioral analysis)
- Proper TLS library (addresses Layer 5: TLS fingerprinting)
- Consistent fingerprint (addresses Layer 6: HTTP/2 fingerprinting)
Implementation with Playwright
from playwright.async_api import async_playwright
import asyncio
async def scrape_cloudflare_site(url, proxy_config):
async with async_playwright() as p:
browser = await p.chromium.launch(
headless=True,
args=[
'--disable-blink-features=AutomationControlled',
]
)
context = await browser.new_context(
proxy=proxy_config,
viewport={'width': 1920, 'height': 1080},
user_agent='Mozilla/5.0 (Windows NT 10.0; Win64; x64) '
'AppleWebKit/537.36 (KHTML, like Gecko) '
'Chrome/120.0.0.0 Safari/537.36',
locale='en-SG',
timezone_id='Asia/Singapore'
)
page = await context.new_page()
# Remove automation flags
await page.add_init_script("""
Object.defineProperty(navigator, 'webdriver', { get: () => undefined });
window.chrome = { runtime: {} };
""")
# Navigate and wait for Cloudflare challenge to complete
await page.goto(url, wait_until='networkidle', timeout=60000)
# Check if we passed the challenge
title = await page.title()
if 'just a moment' in title.lower():
# Still on challenge page, wait longer
await page.wait_for_timeout(10000)
await page.wait_for_load_state('networkidle')
content = await page.content()
cookies = await context.cookies()
await browser.close()
return content, cookies
# Usage
proxy = {
'server': 'http://mobile-proxy.example.com:port',
'username': 'user',
'password': 'pass'
}
content, cookies = asyncio.run(scrape_cloudflare_site(
'https://cloudflare-protected-site.com',
proxy
))For detailed Playwright proxy configuration, see our Playwright proxy setup guide.
Implementation with Puppeteer
const puppeteer = require('puppeteer-extra');
const StealthPlugin = require('puppeteer-extra-plugin-stealth');
puppeteer.use(StealthPlugin());
async function scrapeCloudflare(url, proxyServer, proxyUser, proxyPass) {
const browser = await puppeteer.launch({
headless: 'new',
args: [
`--proxy-server=${proxyServer}`,
'--disable-blink-features=AutomationControlled',
'--no-sandbox'
]
});
const page = await browser.newPage();
await page.authenticate({ username: proxyUser, password: proxyPass });
await page.setViewport({ width: 1920, height: 1080 });
// Navigate and handle challenge
await page.goto(url, { waitUntil: 'networkidle2', timeout: 60000 });
// Wait for challenge resolution
await page.waitForFunction(
() => !document.title.toLowerCase().includes('just a moment'),
{ timeout: 30000 }
).catch(() => console.log('Challenge may not have resolved'));
const content = await page.content();
const cookies = await page.cookies();
await browser.close();
return { content, cookies };
}For the full Puppeteer proxy setup, see our Puppeteer proxy guide.
Cookie Reuse Strategy
Once you pass a Cloudflare challenge, you receive a cf_clearance cookie that is valid for a period (typically 15-30 minutes, configurable by the site owner). Reuse this cookie for subsequent requests to avoid repeated challenges:
import requests
# After obtaining cookies from browser session
cf_cookies = {
'cf_clearance': 'cookie-value-from-browser-session',
'__cf_bm': 'other-cookie-value'
}
# Use cookies in HTTP requests (no browser needed)
session = requests.Session()
session.cookies.update(cf_cookies)
session.headers.update({
'User-Agent': 'same-user-agent-used-in-browser' # Must match
})
# Make requests without browser overhead
response = session.get(
'https://cloudflare-protected-site.com/api/data',
proxies={'http': 'http://user:pass@same-mobile-proxy:port',
'https': 'http://user:pass@same-mobile-proxy:port'}
)The cookie reuse strategy is critical: pass the challenge once with a browser, then use lightweight HTTP requests for the actual scraping. This is faster and consumes less proxy bandwidth.
Success Rate Expectations
Be realistic about success rates. Even with the optimal stack, you will not achieve 100% bypass rates against Cloudflare.
Expected Success Rates by Stack
| Stack | Success Rate (Initial Challenge) | Success Rate (Sustained Scraping) |
|---|---|---|
| Datacenter proxy + requests | 0-5% | 0% |
| Datacenter proxy + headless browser | 5-15% | 2-5% |
| Residential proxy + stealth browser | 50-70% | 30-50% |
| Mobile proxy + stealth browser | 85-95% | 75-90% |
Factors That Affect Success Rate
- Cloudflare plan level: Sites on Enterprise plans have stricter bot detection than those on Free or Pro plans.
- Site-specific rules: Website operators can configure custom security rules that affect bypass difficulty.
- Request volume: Higher volume increases detection risk regardless of proxy quality.
- Time patterns: Scraping during peak hours for the target site’s region looks more natural.
- IP diversity: Using IPs from the carrier that matches the target site’s country improves success rates.
Common Mistakes
Mistake 1: Solving the Challenge Then Switching IPs
If you solve a Cloudflare challenge on one IP and then send subsequent requests from a different IP, Cloudflare will invalidate your cf_clearance cookie. The cookie is bound to the IP that solved the challenge.
Mistake 2: Mismatched Fingerprints
Using a Chrome User-Agent with a Python requests TLS fingerprint. Cloudflare sees the JA3 hash does not match Chrome and flags the request.
Mistake 3: Ignoring Geographic Consistency
A Singapore mobile proxy with a en-US locale and America/New_York timezone. The mismatch between IP geolocation and browser configuration is a detection signal.
Mistake 4: Over-Parallelizing
Sending 50 concurrent requests through one mobile proxy IP. Real mobile users do not generate this pattern. Keep concurrent requests per IP to 3-5.
Conclusion
Bypassing Cloudflare requires addressing every detection layer, and the foundation is IP trust. Mobile proxies provide the highest trust scores because Cloudflare cannot aggressively block mobile carrier IPs without disrupting legitimate users behind CGNAT.
The complete stack — mobile proxies, stealth browser automation, consistent fingerprints, and geographic alignment — gives you the best possible success rate against Cloudflare. It will not be 100%, but 85-95% initial bypass rates are achievable with proper implementation.
DataResearchTools provides Singapore mobile proxies on Singtel, StarHub, and M1 carrier networks. These are real 4G/5G connections with CGNAT architecture that scores in Cloudflare’s lowest risk tier. Start your Cloudflare bypass setup with our mobile proxies and see the difference carrier-grade IP trust makes.
- Bypassing Akamai Bot Manager with Mobile Proxies
- CAPTCHA Handling Strategies: Proxies, Solvers, and Prevention
- How Anti-Bot Systems Detect Scrapers (Cloudflare, Akamai, PerimeterX)
- Rate Limiting and Throttling: How to Scrape Without Triggering Blocks
- Proxy Rotation Strategies for Web Scraping: What Actually Works
- How Anti-Detect Browsers Work: Browser Fingerprinting Explained
- How Anti-Bot Systems Detect Scrapers (Cloudflare, Akamai, PerimeterX)
- API vs Web Scraping: When You Need Proxies (and When You Don’t)
- ASEAN Data Protection Laws: A Web Scraping Compliance Matrix
- How to Build an Ethical Web Scraping Policy for Your Company
- How to Scrape Amazon Product Data with Proxies: 2026 Python Guide
- How to Scrape Bing Search Results with Python and Proxies
- How Anti-Bot Systems Detect Scrapers (Cloudflare, Akamai, PerimeterX)
- API vs Web Scraping: When You Need Proxies (and When You Don’t)
- aiohttp + BeautifulSoup: Async Python Scraping
- ASEAN Data Protection Laws: A Web Scraping Compliance Matrix
- Axios + Cheerio: Lightweight Node.js Scraping
- How to Build an Ethical Web Scraping Policy for Your Company
- How Anti-Bot Systems Detect Scrapers (Cloudflare, Akamai, PerimeterX)
- API vs Web Scraping: When You Need Proxies (and When You Don’t)
- aiohttp + BeautifulSoup: Async Python Scraping
- ASEAN Data Protection Laws: A Web Scraping Compliance Matrix
- Axios + Cheerio: Lightweight Node.js Scraping
- How to Build an Ethical Web Scraping Policy for Your Company
- How Anti-Bot Systems Detect Scrapers (Cloudflare, Akamai, PerimeterX)
- API vs Web Scraping: When You Need Proxies (and When You Don’t)
- aiohttp + BeautifulSoup: Async Python Scraping
- ASEAN Data Protection Laws: A Web Scraping Compliance Matrix
- Axios + Cheerio: Lightweight Node.js Scraping
- How to Build an Ethical Web Scraping Policy for Your Company
Related Reading
- How Anti-Bot Systems Detect Scrapers (Cloudflare, Akamai, PerimeterX)
- API vs Web Scraping: When You Need Proxies (and When You Don’t)
- aiohttp + BeautifulSoup: Async Python Scraping
- ASEAN Data Protection Laws: A Web Scraping Compliance Matrix
- Axios + Cheerio: Lightweight Node.js Scraping
- How to Build an Ethical Web Scraping Policy for Your Company