May 7, 2026 · 7 min read

Puppeteer with Residential Proxy in 2026: Complete Setup Guide

If you're using Puppeteer for scraping or browser automation and getting blocked by Cloudflare, DataDome, or PerimeterX — a residential proxy is the most important fix you can make. This guide covers exactly how to configure one, with working 2026 code examples, common mistakes to avoid, and an honest comparison of Puppeteer vs Playwright for anti-bot bypass.

Marionette strings descending to a browser puppet — Puppeteer residential proxy illustration

Why You're Getting Blocked (Even with a Proxy)

Most developers reach for a proxy when they start getting blocked. That's the right instinct, but many miss a critical detail: bot detection in 2026 runs two separate checks, not one.

A datacenter proxy only changes your IP but keeps it in the "data center range" — Cloudflare already knows those subnets. A residential proxy routes your traffic through a real home internet connection with an ISP-assigned IP, which passes Check 1. You still need to handle Check 2 separately.

The common mistake: Using a premium datacenter proxy (Luminati, Oxylabs enterprise, Bright Data shared) and wondering why Cloudflare still blocks you. Datacenter ≠ residential. You need a genuinely ISP-assigned IP.
Handshake icon — proxy authentication in Puppeteer

How to Add a Residential Proxy to Puppeteer

Puppeteer passes proxy settings via the --proxy-server launch argument. For authenticated proxies (all residential providers require credentials), you also need to call page.authenticate().

const puppeteer = require('puppeteer');

const browser = await puppeteer.launch({
  headless: 'new',
  args: [
    // Point to your residential proxy
    '--proxy-server=http://ro.yourprovider.com:10001',
    // Required for modern Chromium
    '--no-sandbox',
    '--disable-setuid-sandbox',
  ]
});

const page = await browser.newPage();

// Residential proxies require authentication
await page.authenticate({
  username: 'your_username',
  password: 'your_password',
});

await page.goto('https://example.com');
console.log(await page.title());
await browser.close();
page.authenticate() applies per-page: If you open multiple pages/tabs, call authenticate() on each one. It doesn't carry over from the browser context.

Country Selection with Residential Proxies

Different residential providers handle country selection differently. The two most common patterns:

Pattern 1: Separate hostname per country (Decodo, Smartproxy)

// Romania
'--proxy-server=http://ro.decodo.com:10001'

// United States
'--proxy-server=http://us.decodo.com:10001'

// Japan
'--proxy-server=http://jp.decodo.com:10001'

Pattern 2: Session string in username (most providers)

// US residential, sticky session
page.authenticate({
  username: 'user-country-us-session-abc123',
  password: 'your_password',
});

The Fingerprinting Problem (Why a Proxy Isn't Enough)

Even with a residential IP, headless Puppeteer fails bot detection checks because the browser fingerprint is obviously robotic:

You need to patch all of these. The puppeteer-extra + puppeteer-extra-plugin-stealth combination helps, but it's increasingly ineffective against Cloudflare's 2026 detection algorithms — partly because it only patches the fingerprint, not the IP.

const puppeteer = require('puppeteer-extra');
const StealthPlugin = require('puppeteer-extra-plugin-stealth');

puppeteer.use(StealthPlugin());

const browser = await puppeteer.launch({
  headless: 'new',
  args: ['--proxy-server=http://ro.yourprovider.com:10001']
});

// Still need to manually set locale/timezone to match proxy country
const page = await browser.newPage();
await page.authenticate({ username: 'user', password: 'pass' });
await page.setExtraHTTPHeaders({ 'Accept-Language': 'ro-RO,ro;q=0.9' });
// Timezone still requires CDP: Emulation.setTimezoneOverride
Venn diagram with overlapping circles — Puppeteer vs Playwright
Puppeteer's proxy auth model dates from 2018. It shows.

Puppeteer vs Playwright for Residential Proxy in 2026

If you're starting a new project or willing to migrate, Playwright handles residential proxies much more cleanly than Puppeteer. Here's the comparison:

FeaturePuppeteerPlaywright
Proxy config--proxy-server arg + page.authenticate()Built-in proxy option in context (no workaround)
Multi-page proxy authMust call authenticate() on each pageSet once in context, applies everywhere
Browser enginesChrome/Chromium onlyChromium, Firefox, WebKit
Stealth pluginspuppeteer-extra-plugin-stealth (less maintained)playwright-extra stealth + Human Browser
Timezone/locale overrideCDP only, complexBuilt-in: timezoneId, locale in context
2026 maintenance activityStable but slower feature paceActive Microsoft-backed development

For pure Playwright with residential proxy, see our guide: Playwright with Residential Proxy: Complete Setup Guide 2026. And if your specific target is Cloudflare, the dedicated walkthrough is how to bypass Cloudflare with Playwright.

The Easiest Solution: Human Browser (Playwright Drop-in)

If you're tired of wiring together puppeteer-extra, stealth plugins, proxy credentials, timezone patches, and User-Agent strings — Human Browser packages all of it into a single function call. It's Playwright-based but the API is identical to what Puppeteer users expect:

import { launchHuman } from '@virixlabs/humanbrowser';

// Residential IP (Romania by default; needs a Human Browser balance, try it for $1)
// iPhone 15 Pro fingerprint (Canvas, WebGL, fonts all consistent)
// Human-like behavior (Bezier mouse, 60-220ms typing, scroll patterns)
const { browser, page } = await launchHuman({ country: 'us' });

await page.goto('https://cloudflare-protected-site.com');
console.log(await page.title());

await browser.close();

What it handles automatically:

Stop Fighting Proxies — Just Use Human Browser. Pay-as-you-go: $0.10/hr browser time + $0.02 per agent step (AI included) + $4/GB residential proxy, no subscription, try it for $1, then top up from $5. Works on Cloudflare, DataDome, PerimeterX. Drop-in for Playwright. Human Browser — pay as you go, no subscription

Debugging Proxy Issues in Puppeteer

Common problems and fixes:

ERR_TUNNEL_CONNECTION_FAILED

The proxy server address or port is wrong, or the proxy requires a different connection protocol (SOCKS5 vs HTTP). Check the exact host:port from your provider dashboard.

407 Proxy Authentication Required

You're not calling page.authenticate(), or the credentials are wrong. Note: authenticate() must be called before goto().

Still getting Cloudflare 403 with residential proxy

Your IP is residential but the fingerprint is still headless. Add puppeteer-extra-plugin-stealth and manually override timezone/locale to match the proxy country. Or switch to Human Browser which handles all of this automatically.

proxy.authenticate() not working on new pages

This is a known Puppeteer limitation — proxy authentication must be set per-page. Wrap your page creation in a helper function that calls authenticate() immediately after newPage().

FAQ

How do I add a proxy to Puppeteer?

Pass --proxy-server=http://host:port to puppeteer.launch({ args: [...] }). For authenticated proxies, call page.authenticate({ username, password }) after creating each page.

Does Puppeteer support residential proxies?

Yes — Puppeteer supports any HTTP, HTTPS, or SOCKS5 proxy including residential. You need credentials from a residential provider (Decodo, Bright Data, Webshare) and must pass them via page.authenticate().

Why is Puppeteer still getting blocked even with a residential proxy?

Bot detection in 2026 checks both IP reputation and browser fingerprint. A residential proxy fixes the IP check but headless Chromium still fails on Canvas, WebGL, fonts, and TLS fingerprint. Use puppeteer-extra-plugin-stealth or switch to Human Browser which patches everything automatically.

Should I use Puppeteer or Playwright with a residential proxy?

Playwright is the better choice in 2026. It has built-in proxy support per-context (no need to call authenticate() on each page), supports multiple browser engines, and the stealth ecosystem is more actively maintained.

What's the best free residential proxy for Puppeteer testing?

Human Browser lets you try it for $1 — about 4 typical tasks, enough to verify your setup works. After that, top up from $5 — billing is pay-as-you-go, no subscription.

Related Guides

Top up — $20

Loading secure checkout…

More coins →