How to set up an authenticated proxy in Puppeteer (Node.js)
Updated:
Puppeteer controls Chrome and Chromium over the DevTools Protocol (CDP), providing a native await page.authenticate({ username, password }) API for HTTP 407 proxy authentication. Pairing --proxy-server=http://ip:port with page.authenticate() lets your Node.js scrapers route through VinaProxy static proxies without any external browser extensions.
--proxy-server=http://ip:port + page.authenticate({ username, password })- 1 IP₫40,000
- 5+ IPs₫35,000
- 10+ IPs₫25,000
- 20+ IPs₫25,000
- 50+ IPs₫25,000
- 100+ IPs₫25,000
- 200+ IPs₫25,000
- 500+ IPs₫25,000
- 1000+ IPs₫22,000
- 2000+ IPs₫20,000
- 1 IP₫40,000
- 5+ IPs₫35,000
- 10+ IPs₫25,000
- 20+ IPs₫25,000
- 50+ IPs₫25,000
- 100+ IPs₫25,000
- 200+ IPs₫25,000
- 500+ IPs₫25,000
- 1000+ IPs₫22,000
- 2000+ IPs₫20,000
Two-step proxy configuration in Puppeteer
Never embed user:pass@ inside the --proxy-server launch argument. Instead, pass the host and port at launch and authenticate on the Page instance:
| Step | Puppeteer Code | Why It Matters |
|---|---|---|
| 1. Launch Chromium | puppeteer.launch({ args: ['--proxy-server=http://ip:port'] }) | Points Chromium's network socket at your VinaProxy proxy |
| 2. Authenticate Page | await page.authenticate({ username, password }) | Supplies CDP credentials for HTTP 407 challenges |
| 3. Navigate | await page.goto(url, { waitUntil: 'domcontentloaded' }) | Loads the target URL through the authenticated tunnel |
Rotating multiple proxies across tabs with proxy-chain
- Remember that
page.authenticate()is scoped perPagetab—call it on every new tab returned bybrowser.newPage() - To use different proxies across incognito contexts inside a single Chromium process, wrap each
http://user:pass@ip:portURL with theproxy-chainnpm package (anonymizeProxy()) and passproxyServertobrowser.createBrowserContext({ proxyServer }) - Compatible with
puppeteer-extraandpuppeteer-extra-plugin-stealth
Step by step
- 1
Pass --proxy-server=http://ip:port to puppeteer.launch()
Launch the browser with
const browser = await puppeteer.launch({ args: ['--proxy-server=http://ip:port'] });. - 2
Call await page.authenticate() on the new page
Open a tab with
const page = await browser.newPage();and callawait page.authenticate({ username: 'USER', password: 'PASS' });. - 3
Test the exit IP address
Run
await page.goto('https://vinaproxy.com/api/my-ip');and inspect the returned JSON. - 4
Clean up browser processes
Call
await browser.close();when the job finishes.
Frequently asked questions
Why does Puppeteer throw `ERR_NO_SUPPORTED_PROXIES`?
That error occurs if you include user:pass@ inside --proxy-server=http://user:pass@ip:port. Keep --proxy-server=http://ip:port clean and pass credentials via await page.authenticate({ username, password }).
Why did a second tab opened with `browser.newPage()` fail with HTTP 407?
page.authenticate() applies per tab. Call await secondPage.authenticate({ username, password }) before navigating on any newly opened tab.
Are VinaProxy proxies unmetered for headless Chrome scraping?
Yes. All Dedicated IPv4 and Static ISP plans include unlimited monthly bandwidth.
Power your Node.js Puppeteer fleet with static IPs
Instant unmetered Dedicated IPv4 and Static ISP proxies across 7 countries.
Buy Puppeteer Proxies