Basic SOCKS5 setup
Chrome supports SOCKS proxies through the same flag as HTTP proxies:
import puppeteer from 'puppeteer';
const browser = await puppeteer.launch({
args: ['--proxy-server=socks5://203.0.113.10:1080'],
});
const page = await browser.newPage();
await page.goto('https://httpbin.org/ip');
console.log(await page.evaluate(() => document.body.innerText));
await browser.close();For an overview of the protocol, see SOCKS5 proxies. For Puppeteer proxies in general, see the Puppeteer proxies pillar.
The authentication problem
Chrome doesn't support username/password authentication for SOCKS5 proxies. page.authenticate() only answers HTTP proxy challenges. If your SOCKS5 proxy requires credentials, connections will fail.
You have two good workarounds.
Workaround 1: IP whitelisting
Add your server's IP to the provider's whitelist, and use the SOCKS5 endpoint without credentials. Simplest and fastest.
Workaround 2: A local forwarder
Run a local proxy without authentication that forwards to the authenticated SOCKS5 upstream. proxy-chain can do this in Node:
import puppeteer from 'puppeteer';
import proxyChain from 'proxy-chain';
const local = await proxyChain.anonymizeProxy('socks5://USER:PASS@socks.example.com:1080');
const browser = await puppeteer.launch({ args: [`--proxy-server=${local}`] });
// ...
await browser.close();
await proxyChain.closeAnonymizedProxy(local, true);Alternatively, standalone tools such as gost can expose a local unauthenticated HTTP or SOCKS listener that forwards to an authenticated upstream:
gost -L http://127.0.0.1:8080 -F socks5://USER:PASS@socks.example.com:1080Then point Puppeteer at http://127.0.0.1:8080.

DNS resolution
When Chrome uses a SOCKS5 proxy, it sends hostnames to the proxy for resolution rather than resolving locally, which helps prevent DNS leaks. You can additionally pass a host resolver rule to make sure nothing resolves locally:
args: [
'--proxy-server=socks5://203.0.113.10:1080',
'--host-resolver-rules=MAP * ~NOTFOUND , EXCLUDE 203.0.113.10',
]The EXCLUDE entry ensures the proxy's own address can still be resolved.
Per-context SOCKS5
With recent Puppeteer versions you can set SOCKS5 per browser context:
const ctx = await browser.createBrowserContext({ proxyServer: 'socks5://203.0.113.10:1080' });The same authentication limitation applies. See Puppeteer proxy per page.
SOCKS5 or HTTP for Puppeteer?
For browser automation, HTTP(S) proxies are usually more convenient because page.authenticate() works. Choose SOCKS5 when your provider only offers SOCKS5 for the product you need, or when you want proxy-side DNS without extra configuration.
Proxy tip: If you need a pool to run this against, Geonode works with every tool in this guide: rotate per request for stateless pages, or hold a sticky session for logins and pagination. See using Geonode with Puppeteer for working code.
Troubleshooting
| Error | Cause | Fix |
|---|---|---|
ERR_SOCKS_CONNECTION_FAILED | Wrong host/port, credentials required, proxy down | Check endpoint; whitelist IP or use forwarder |
ERR_PROXY_CONNECTION_FAILED | HTTP scheme used for a SOCKS port, or vice versa | Use the right scheme and port |
| Timeouts | Slow proxy | Increase timeout; test speed |
See common proxy errors.
When you might prefer SOCKS5 in Puppeteer
- Your provider only offers a product over SOCKS5, such as some mobile proxy ports.
- You want proxy-side DNS without extra configuration.
- You're routing through an SSH tunnel (
ssh -D 1080 user@servercreates a local SOCKS5 proxy).
Using an SSH tunnel as a SOCKS5 proxy
ssh -N -D 1080 user@your-server.example.comconst browser = await puppeteer.launch({ args: ['--proxy-server=socks5://127.0.0.1:1080'] });All browser traffic exits from your server's IP, with no proxy credentials needed because the tunnel is local. This is a handy way to give Puppeteer a stable datacenter IP you control.
Verifying DNS goes through the proxy
- Launch with the SOCKS5 proxy and the host resolver rule.
- Visit a DNS leak test page.
- Confirm the resolvers shown are near the proxy, not your local network.
Mixing SOCKS5 and HTTP proxies
With per-context proxies, one context can use a SOCKS5 proxy and another an HTTP proxy in the same browser. This is useful when different providers or products use different protocols. See Puppeteer proxy per page.
Performance notes
SOCKS5 and HTTP CONNECT tunnels perform similarly for browser traffic. If SOCKS5 feels slower, the cause is usually the proxy's location or exit quality, not the protocol. See proxy speed test.
For the full Puppeteer picture, see our Puppeteer proxies pillar guide.
Budget tip: Webshare is easy to plug into the tools in this guide: point your client at its backbone gateway and add a rotate or session suffix to the username, or download a direct proxy list and rotate it yourself. See using Webshare with Puppeteer.
SOCKS5 quick reference for Puppeteer
| Need | Solution |
|---|---|
| Unauthenticated SOCKS5 | --proxy-server=socks5://host:port |
| Authenticated SOCKS5 | IP whitelisting, or proxy-chain/gost local forwarder |
| Per-context SOCKS5 | createBrowserContext({ proxyServer: 'socks5://...' }) |
| No local DNS | --host-resolver-rules with an EXCLUDE for the proxy host |
| SSH tunnel | ssh -N -D 1080 user@server then socks5://127.0.0.1:1080 |
| Verify exit | Navigate to an IP echo page |
See SOCKS4 vs SOCKS5 and best SOCKS5 proxies.
A gost forwarder as an alternative to proxy-chain
If you'd rather not add a Node dependency, or you want the same forwarder for several tools, gost does the job as a single binary. It listens locally without authentication and forwards to your authenticated SOCKS5 upstream:
gost -L http://127.0.0.1:8080 -F socks5://USER:PASS@socks.example.com:1080Then point Puppeteer at the local listener:
const browser = await puppeteer.launch({
args: ['--proxy-server=http://127.0.0.1:8080'],
});Chrome talks plain HTTP proxy to gost on your machine, and gost handles the SOCKS5 handshake and credentials. You can also listen as SOCKS5 locally (-L socks5://127.0.0.1:1080) if you want Chrome to keep using SOCKS.
A few precautions:
- Bind to 127.0.0.1, never
0.0.0.0, or anyone who can reach your server can use your proxy without a password. - Run one listener per upstream identity if different pages need different exits, each on its own port.
- Check DNS goes through the proxy. Test with a DNS leak page as described above.
The same pattern works for Selenium, Playwright and command-line tools. For more forwarding patterns, see proxy chains; for the protocol background, SOCKS5 proxies.
If you're weighing Rayobyte as well, Using Rayobyte Proxies With Puppeteer explains which of its products fits, and Rayobyte vs Geonode vs Webshare for Puppeteer puts it side by side with Geonode and Webshare.
Residential tip: For lenient targets, Rayobyte rotating datacenter traffic costs about $0.30 per GB pay as you go, and you can move only the blocked domains to residential. Our guide to using Rayobyte with Puppeteer shows the setup.
Key takeaways
- Puppeteer uses SOCKS5 via
--proxy-server=socks5://host:port, per browser or per context. - Chrome doesn't support SOCKS5 username/password, so use IP whitelisting or a local forwarder (proxy-chain, gost).
- Chrome resolves DNS through SOCKS5 by default; host resolver rules add extra protection against leaks.
- An SSH dynamic tunnel is a quick way to give Puppeteer a SOCKS5 exit through your own server.
- HTTP proxies are usually more convenient for Puppeteer because
page.authenticate()works. See puppeteer proxy authentication.
If SOCKS5 support is a must, check it per product when you compare providers in our guide to the best proxies in 2026.
FAQ
Does Puppeteer support SOCKS5 authentication?
Not natively, because Chrome doesn't. Use IP whitelisting or a local forwarder.
Does SOCKS4 work in Puppeteer?
Yes, with socks4://, but SOCKS5 is preferred. See SOCKS4 vs SOCKS5.
Can Puppeteer send UDP through SOCKS5?
Chrome's SOCKS support is for TCP connections; don't rely on UDP relay.
Sources and further reading
Independent references that back up the points above, from standards bodies, governments, universities and non-profits. They open in a new tab.
- RFC 1928: SOCKS Protocol Version 5 (IETF / RFC Editor): The original specification of SOCKS5, including UDP support and authentication negotiation.
- RFC 9110: HTTP Semantics (IETF / RFC Editor): The HTTP standard that defines how proxies, tunnels and the CONNECT method behave.
- SP 800-63B: Authentication and Authenticator Management (NIST): NIST's guidance on passwords and authentication, relevant to proxy credentials and accounts.
- Proxy servers and tunneling (MDN Web Docs (Mozilla)): Mozilla's developer explainer on forward proxies, reverse proxies and tunneling.
- 407 Proxy Authentication Required (MDN Web Docs (Mozilla)): The status code a proxy returns when credentials are missing or wrong.
Editorial note: Proxy providers change their pools, features and prices often, so treat any figures here as typical ranges at the time of writing and confirm current terms with the provider before you buy.