New v5.5.1: balance-first checkout — add funds once, buy instantly. Read more

Using SOCKS5 proxies with Puppeteer and Playwright

Chromium does not support username and password authentication on SOCKS5 proxies. Three working setups — IP whitelisting, the HTTP port, and a local forwarder — with code for Puppeteer and Playwright, plus DNS and WebRTC leak checks.

On this page

Headless browsers are the most reliable way to collect from JavaScript-heavy sites, and SOCKS5 is often the protocol people reach for first. There is one catch that costs teams hours: Chromium cannot authenticate to a SOCKS5 proxy with a username and password. It accepts socks5://host:port, but ignores credentials, and authentication helpers such as Puppeteer's page.authenticate() only apply to HTTP proxies.

This guide shows three setups that work, how to verify there are no leaks, and when SOCKS5 is actually worth it.

Do you need SOCKS5 at all?

For a browser loading web pages, the HTTP port of the proxy is functionally equivalent. HTTPS traffic is tunnelled end-to-end with CONNECT, so the proxy never sees page content, and the target sees exactly the same TLS handshake.

SOCKS5 is useful when:

  • you also proxy non-HTTP TCP traffic from the same tool;
  • a library or antidetect browser only exposes SOCKS settings;
  • you want the proxy, not the client, to resolve hostnames (with SOCKS5, Chromium sends the hostname to the proxy and DNS is resolved on the exit side).

If none of these apply, use the HTTP port with credentials and skip to the leak checks.

Setup 1: IP whitelisting (simplest)

All our products support IP-whitelist authentication as an alternative to username and password. Add the public IP of the machine running your browsers to the whitelist in the dashboard, and the proxy accepts connections from it without credentials. Chromium is then happy with a plain SOCKS5 URL.

On mobile proxies, the SOCKS5 port is the HTTP port plus 10,000: if your HTTP port is 12345, SOCKS5 is 22345.

Puppeteer

const puppeteer = require('puppeteer');

const browser = await puppeteer.launch({
  args: ['--proxy-server=socks5://fr.mobile.gw.proxuno.com:22345'],
});
const page = await browser.newPage();
await page.goto('https://api.ipify.org');
console.log(await page.evaluate(() => document.body.innerText));
await browser.close();

Playwright

const { chromium } = require('playwright');

const browser = await chromium.launch({
  proxy: { server: 'socks5://fr.mobile.gw.proxuno.com:22345' },
});
const page = await browser.newPage();
await page.goto('https://api.ipify.org');
console.log(await page.textContent('body'));
await browser.close();

Whitelisting works well for fixed servers. It is less convenient on laptops or CI runners whose public IP changes.

Setup 2: the HTTP port with credentials

If you cannot whitelist, use the HTTP port. Both frameworks handle HTTP proxy authentication natively.

Puppeteer

const browser = await puppeteer.launch({
  args: ['--proxy-server=http://fr.mobile.gw.proxuno.com:12345'],
});
const page = await browser.newPage();
await page.authenticate({ username: 'USER', password: 'PASS' });
await page.goto('https://example.com');

Playwright — per context, which is useful when each context should use a different proxy or residential session:

const browser = await chromium.launch();
const context = await browser.newContext({
  proxy: { server: 'http://fr.mobile.gw.proxuno.com:12345', username: 'USER', password: 'PASS' },
});

Setup 3: a local forwarder

When a tool insists on SOCKS5 and you cannot whitelist, run a small local proxy without authentication that forwards to the remote proxy with credentials. The browser talks to 127.0.0.1, the forwarder handles authentication upstream.

In Node.js, the proxy-chain package does this in a few lines:

const ProxyChain = require('proxy-chain');

const upstream = 'http://USER:[email protected]:12345';
const local = await ProxyChain.anonymizeProxy(upstream);   // e.g. http://127.0.0.1:41235

const browser = await puppeteer.launch({ args: [`--proxy-server=${local}`] });
// …
await browser.close();
await ProxyChain.closeAnonymizedProxy(local, true);

The same idea works with any local forwarder. Bind it to 127.0.0.1 only — an unauthenticated proxy listening on a public interface is an open relay.

Check for leaks

A misconfigured browser can reveal your real network in three ways. Test each one before running a job at scale.

1. The visible IP

Open an IP echo service through the proxy and compare it with the proxy's current IP in the dashboard.

2. DNS

With an HTTP proxy, hostnames in CONNECT requests are resolved by the proxy. With SOCKS5 in Chromium, hostnames are also sent to the proxy. Problems appear when another component (a local forwarder, a VPN client, a custom DNS-over-HTTPS setting) resolves names locally first. Use a DNS leak test page through the browser and check that the resolvers shown belong to the proxy's country and network, not yours.

3. WebRTC

WebRTC can discover local and public addresses through STUN over UDP, bypassing the proxy entirely. In automation, restrict it:

args: [
  '--proxy-server=socks5://fr.mobile.gw.proxuno.com:22345',
  '--force-webrtc-ip-handling-policy=disable_non_proxied_udp',
],

With this policy, WebRTC only uses connections that go through the proxy. Most antidetect browsers expose an equivalent setting.

Performance notes

  • Reuse browsers, not just pages. Launching Chromium is the slowest step; keep one browser and create a context per identity.
  • Block what you do not need. Request interception that aborts images, fonts and media cuts traffic — and residential cost — substantially on content-heavy sites.
  • Mind concurrency per IP. Ten tabs on one mobile proxy look like ten users behind one CGNAT address, which is normal; a hundred do not.
  • Rotate between contexts, not during them. On a mobile proxy, call the rotation API after closing a context and before opening the next one.

Summary

Situation Setup
Fixed server, any protocol IP whitelist + SOCKS5 or HTTP
Changing IP, browser only HTTP port with credentials
Tool requires SOCKS5, cannot whitelist Local forwarder

The Puppeteer and Playwright integration guide has complete, maintained examples, and the IP whitelist documentation explains how to add addresses and CIDR ranges.

Related articles

All articles

Guides

Buying proxies with crypto in 2026 — what actually matters

Who accepts cryptocurrency for proxies in 2026, what the payment really changes, and how to pick between dedicated mobile modems, rotating residential pools and static ISP IPs when you pay in BTC, XMR or USDT.

5 min read

Guides

Paying with crypto: networks, fees and confirmations

How to top up your balance on the supported crypto networks, send the order reference and transaction ID to support and wait for manual verification before your balance is credited.

5 min read

Guides

Sticky sessions and cookie handling, now up to 30 minutes

Residential sticky sessions can now last up to 30 minutes. How sessions work at the gateway, how to pair them with cookie jars so each identity stays consistent, and what to do when a peer disappears mid-session.

4 min read