How to use proxies with Puppeteer
Launch Puppeteer with args: ["--proxy-server=http://HOST:PORT"], then call await page.authenticate({ username: "USERNAME", password: "PASSWORD" }) before page.goto. Chrome ignores credentials inside --proxy-server, so page.authenticate is required.
What you need
- An active CleanProxies plan: static ISP proxies for fixed US IPs, or rotating residential / mobile proxies for pools. The trial works too.
- Your credential line from the dashboard's proxy manager: host (or IP), port, username and password.
- Node.js 20+ and
npm install puppeteer(it downloads a matching Chrome).
New to proxies? For the overview, read Proxies with Python Requests, Playwright and Puppeteer and Rotating vs sticky sessions. This guide goes deeper on Puppeteer only.
Your CleanProxies credentials
| Product | Line in your dashboard | Notes |
|---|---|---|
| Static ISP proxies | IP:PORT:USER:PASS | One line per dedicated IP. With IP whitelisting turned on, the line is just IP:PORT and no password is sent. |
| Rotating residential and mobile | HOST:PORT:USER:PASS | Generated in the proxy manager. The username carries the location and session you pick, so generate a new list to change them. |
Most tools want the same details as a URL: http://USERNAME:PASSWORD@HOST:PORT for HTTP(S) or socks5://USERNAME:PASSWORD@HOST:PORT for SOCKS5. The examples on this page use those placeholders; copy the host, port, username and password from your CleanProxies dashboard. To convert a whole list at once, paste it into the proxy list formatter.
How to set up CleanProxies in Puppeteer
- 1
Launch with the proxy
Pass--proxy-server=http://HOST:PORTinargs. Leave the credentials out of this flag. - 2
Authenticate each page
Callpage.authenticate({ username, password })on every new page before it navigates. - 3
Navigate
Open your target. HTTPS sites tunnel through the proxy end to end. - 4
Check the exit IP
Go tohttps://api.ipify.organd read the page text.
Puppeteer proxy example
import puppeteer from "puppeteer";
const browser = await puppeteer.launch({
args: ["--proxy-server=http://HOST:PORT"],
});
const page = await browser.newPage();
await page.authenticate({ username: "USERNAME", password: "PASSWORD" });
await page.goto("https://api.ipify.org", { waitUntil: "domcontentloaded" });
console.log("Exit IP:", await page.evaluate(() => document.body.innerText));
await browser.close();A different proxy per browser context
One browser can run several isolated contexts, each with its own proxy, cookies and storage. That's the efficient way to run many accounts or locations in one Chrome process.
const lines = ["IP1:PORT:USER1:PASS1", "IP2:PORT:USER2:PASS2"];
for (const line of lines) {
const [host, port, username, ...rest] = line.split(":");
const context = await browser.createBrowserContext({ proxyServer: `http://${host}:${port}` });
const page = await context.newPage();
await page.authenticate({ username, password: rest.join(":") });
await page.goto("https://api.ipify.org");
console.log(await page.evaluate(() => document.body.innerText));
await context.close();
}SOCKS5 and leak prevention
- Chrome supports no authentication method for SOCKS5, so
page.authenticatecan't answer a SOCKS5 proxy. Use the HTTP form of your CleanProxies line, or SOCKS5 on an ISP proxy authorized by IP whitelisting (--proxy-server=socks5://IP:PORT). - With an HTTP proxy, Chrome sends the hostname in the CONNECT request, so DNS is resolved on the proxy side.
- Add
--force-webrtc-ip-handling-policy=disable_non_proxied_udptoargsso WebRTC can't reveal your server's IP.
Static ISP vs rotating residential in Puppeteer
Static ISP proxies
Map one dedicated US ISP IP to one browser context per account. The IP never rotates, so cookies, fingerprint and address stay consistent across runs.
Rotating residential proxies
A rotating line can change IP between connections, which breaks logins mid-flow. For Puppeteer, generate sticky lines in the CleanProxies dashboard; use rotating lines only for single-page, logged-out fetches.
Verify your exit IP
The first example prints the exit IP. For a fuller check, open What is my IP? in the proxied page and take a screenshot.
Open What is my IP? through the proxy to see the address and headers a website receives, or paste up to ten lines into the free proxy checker to test connectivity, latency and exit IP before you start.
Troubleshooting Puppeteer proxy errors
| Problem | Likely cause | Fix |
|---|---|---|
| net::ERR_TUNNEL_CONNECTION_FAILED | The proxy refused the CONNECT, usually missing or wrong credentials. | Call page.authenticate before goto on every page, with the exact dashboard credentials. |
| net::ERR_PROXY_CONNECTION_FAILED | Wrong host or port, or blocked outbound traffic. | Test the line with curl -x; check the port. |
| Auth works on the first page only | authenticate is per page. | Call it for each new page, including popups. |
| SOCKS5 with credentials fails | Chrome doesn't support SOCKS5 authentication. | Switch to http:// or use IP whitelisting. |
| WebRTC leak | WebRTC uses non-proxied UDP. | Add --force-webrtc-ip-handling-policy=disable_non_proxied_udp. |
Still stuck? Our 24/7 support team answers fast: contact us with the error and the line you used (leave the password out).
Puppeteer proxy FAQs
No. Chrome ignores credentials in that flag. Pass them with page.authenticate instead.