Playwright Troubleshooting · 2026

playwright-stealth Not Working in 2026 — Here's the Real Fix

Feb 19, 2026 8 min read by Virix Labs

⚠️ TL;DR: playwright-extra stealth patches fingerprints but does nothing about your IP. Cloudflare and DataDome block your VPS IP regardless of fingerprint. Fix: add a residential proxy.

You've installed playwright-extra and puppeteer-extra-plugin-stealth. You patched navigator.webdriver. You're spoofing user agents. And yet — your scraper is still getting blocked in 2026.

This guide explains exactly why playwright-stealth fails in 2026 and gives you the working combination that bypasses Cloudflare, DataDome, and PerimeterX reliably.

Why playwright-stealth stopped working

The playwright-extra stealth plugin was designed to hide browser automation signatures at the JavaScript layer. It patches things like:

  • navigator.webdriverundefined
  • Chrome runtime object presence
  • Permission API behavior
  • WebGL renderer strings

These were the primary bot detection vectors in 2020–2022. But bot detection has evolved significantly. Modern systems like Cloudflare Bot Management, DataDome, and PerimeterX v3 now run a two-layer check:

Layer 1: IP Reputation

Your request hits Cloudflare's edge before any JavaScript fingerprinting. Cloudflare checks your IP against its threat intelligence database in milliseconds. A data center IP (AWS, GCP, Hetzner, Contabo, OVH) is flagged as "non-residential" and scored as high-risk. This check happens at the network layer — no JavaScript is ever executed.

Layer 2: Browser Fingerprint

If you pass the IP check, Cloudflare then runs browser fingerprinting challenges (Turnstile). This is where playwright-stealth would help — but you're already blocked before you get here.

🔥 The harsh truth: On 90% of Cloudflare-protected sites, your scraper never reaches the JavaScript fingerprinting step. It's blocked at the IP level. No amount of stealth plugin patching will fix this.

The proof: playwright-stealth test results in 2026

SetupCloudflareDataDomePerimeterXAkamai
Vanilla Playwright (datacenter)❌ Blocked❌ Blocked❌ Blocked❌ Blocked
playwright-extra + stealth (datacenter)❌ Blocked⚠️ Sometimes❌ Blocked⚠️ Sometimes
playwright-extra + stealth (datacenter proxy)❌ Blocked❌ Blocked❌ Blocked❌ Blocked
iPhone fingerprint + residential proxy✅ Pass✅ Pass✅ Pass✅ Pass

The working solution in 2026

You need two things working together:

  1. Residential IP — a real home IP assigned by an ISP (DIGI Romania, AT&T, BT, etc.), not a data center
  2. Realistic fingerprint — iPhone 15 Pro on iOS Safari passes all known fingerprint challenges as of 2026

Option A: human-browser (quickest)

The human-browser npm package combines both into a single function call. It uses iPhone 15 Pro fingerprinting plus routes through a residential proxy automatically:

npm install human-browser

# Set your proxy credentials
export PROXY_HOST=brd.superproxy.io
export PROXY_PORT=22225
export PROXY_USER=brd-customer-xxx-zone-residential-country-us
export PROXY_PASS=your_password
const { launchHuman } = require('human-browser');

const { page } = await launchHuman();

// Works through Cloudflare automatically
await page.goto('https://cloudflare-protected-site.com');
const title = await page.title();
console.log(title); // ✅ actual page title, not "Just a moment..."

Option B: Manual residential proxy setup with playwright-extra

If you want to keep using playwright-extra, add a residential proxy:

const { chromium } = require('playwright-extra');
const stealth = require('puppeteer-extra-plugin-stealth');
chromium.use(stealth());

const browser = await chromium.launch({
  proxy: {
    server: 'http://brd.superproxy.io:22225',
    username: 'brd-customer-hl_xxxxx-zone-residential-country-us',
    password: 'your_password'
  }
});

const ctx = await browser.newContext({
  userAgent: 'Mozilla/5.0 (iPhone; CPU iPhone OS 17_4_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.4.1 Mobile/15E148 Safari/604.1',
  viewport: { width: 393, height: 852 },
  isMobile: true,
  hasTouch: true,
});

Choosing a residential proxy in 2026

Not all residential proxies are equal. Some providers sell "residential" IPs that are actually VPN endpoints on ISP networks — these get flagged quickly. Look for:

  • Real peer-to-peer residential networks (actual home devices)
  • Country/city-level targeting
  • Sticky sessions (same IP for the full browser session)
  • Low "proxy score" on ipqualityscore.com and ipinfo.io

For most use cases, a Romania residential IP is the easiest pass — DIGI Romania has extremely low fraud scores and excellent Cloudflare bypass rates.

Human Browser — plug-and-play residential proxy

Starter plan: Romania residential IP, 2GB/mo, works with Playwright, Puppeteer, and any HTTP client. From $13.99/mo.

See Plans →

Common mistakes when using playwright-stealth

Mistake 1: Using a datacenter proxy with stealth

Adding a Hetzner, AWS, or "cheap residential" proxy that's actually a datacenter IP makes things worse — Cloudflare is more suspicious of traffic from known proxy providers than from VPSes.

Mistake 2: Not setting a mobile user agent

Desktop browser signatures are scrutinized more heavily than mobile in 2026. iPhone Safari has lower bot scores on most challenge systems. Always prefer a mobile fingerprint when you don't need desktop rendering.

Mistake 3: Making too many requests per IP

Even with a residential IP, hammering a site from the same address will get it flagged. Use sticky sessions for multi-step flows and rotate IPs between independent scraping tasks.

Mistake 4: Using playwright-stealth without updating it

The stealth plugin has not been updated in 2024-2026. Some of its patches are now counterproductive — patching certain properties actually creates a new fingerprint that Cloudflare detects. Check the package's GitHub issues before relying on it.

Quick diagnostic checklist

If your scraper is getting blocked, run through this checklist:

  1. Check your IP at ipinfo.io — is it labeled "hosting" or "isp"? Hosting = you need a residential proxy.
  2. Check your IP at scamalytics.com — score above 30 = likely blocked by DataDome.
  3. Try your target URL with curl through the same IP — if curl gets blocked, it's 100% IP-level rejection.
  4. Try a different target URL on the same CDN (e.g., another Cloudflare site) — if that works, the block is site-specific (IP may be fine).