Puppeteer
Proxies for Puppeteer let the tool connect through a different IP address instead of always using the IP of the machine running it. This is useful for location-based tasks, testing, monitoring, and other jobs where the connection source matters.
Puppeteer still handles the main task. The proxy handles where the connection comes from.
What happens without one: IP bans, rate limits, geo walls
Without a proxy, websites keep seeing the same IP. As activity increases, that IP may hit a rate limit or get blocked.
Location can matter too. A page opened from Germany may not return the same content as one opened from the US.
A proxy for Puppeteer makes it possible to connect from different IPs and locations when needed.
Which proxy type to use with Puppeteer
The right proxy type depends on the job.
| Proxy type | Scraping | Account management | Testing | Monitoring |
|---|---|---|---|---|
| Residential | Good when location and IP source matter | Useful when accounts need residential IPs | Good for location-based testing | Useful for checking content from different locations |
| ISP | Good when a stable IP is needed | Useful for longer sessions on one IP | Good for testing with a consistent IP | Useful for ongoing checks from the same IP |
| Datacenter | Good for speed and larger request volumes | Better when residential IPs are not required | Good for general testing | Good for frequent automated checks |
Residential proxies are useful when the IP source and location matter. ISP proxies work well when the same IP needs to stay active for longer. Datacenter proxies make sense when the main focus is speed and scale.
The best option also depends on whether the task needs geo-targeting, a stable connection, or access to a larger pool of IPs.
How to connect a proxy in Puppeteer
The Puppeteer proxy setup needs the Geonode host, port, username, and password. Keep the credentials in environment variables, then load them when setting up the proxy in code.
Using Geonode? Get the username and password from Access Credentials and the host, port, and protocol from Proxy Server Information.
Settings path or code
For Puppeteer, pass the proxy host and port through --proxy-server when launching the browser:
import puppeteer from "puppeteer";
import "dotenv/config";
const browser = await puppeteer.launch({
headless: true,
args: [
`--proxy-server=http://${process.env.GEONODE_PROXY_HOST}:${process.env.GEONODE_PROXY_PORT}`,
],
});Then create the page and provide the proxy credentials:
const page = await browser.newPage();
await page.authenticate({
username: process.env.GEONODE_PROXY_USER,
password: process.env.GEONODE_PROXY_PASS,
});Keep the actual username and password in environment variables instead of putting them directly in the source file. This setup successfully returned HTTP 200 through the proxy in our test.
Authentication format host:port:user:pass
Geonode gives you four values:
proxy.geonode.io:PORT:USERNAME:PASSWORDFor Puppeteer, keep the values separate. Store them in environment variables:
GEONODE_PROXY_HOST=proxy.geonode.io
GEONODE_PROXY_PORT=9000
GEONODE_PROXY_USER=USERNAME
GEONODE_PROXY_PASS=PASSWORDLoad the host and port through --proxy-server, then authenticate the page:
const browser = await puppeteer.launch({
headless: true,
args: [
`--proxy-server=http://${process.env.GEONODE_PROXY_HOST}:${process.env.GEONODE_PROXY_PORT}`,
],
});
const page = await browser.newPage();
await page.authenticate({
username: process.env.GEONODE_PROXY_USER,
password: process.env.GEONODE_PROXY_PASS,
});We tested this with valid credentials and received HTTP 200. With an incorrect password, the proxy returned HTTP 407 and:
Authentication error. Please check your authentication settings.Rotation vs sticky session in Puppeteer
If the requests do not need to keep the same IP, use rotation.
For our test, we launched Puppeteer with the HTTP rotating port:
const browser = await puppeteer.launch({
headless: true,
args: ["--proxy-server=http://proxy.geonode.io:9000"],
});
const page = await browser.newPage();
await page.authenticate({
username: process.env.GEONODE_PROXY_USER,
password: process.env.GEONODE_PROXY_PASS,
});We made five requests using fresh browser sessions:
| Request | IP |
|---|---|
| Request 1 | 108.31.182.167 |
| Request 2 | 45.186.93.125 |
| Request 3 | 109.254.131.42 |
| Request 4 | 109.153.11.141 |
| Request 5 | 37.113.173.139 |
Unique IPs: 5
Rotation: Yes
All five requests returned different IPs in this test. That confirms rotation worked during the run, but it does not guarantee a new IP for every future request.
If related requests need to stay on the same IP, use a sticky session instead. Use the sticky port and add the session details to the username:
const browser = await puppeteer.launch({
headless: true,
args: ["--proxy-server=http://proxy.geonode.io:10000"],
});
const page = await browser.newPage();
await page.authenticate({
username: `${process.env.GEONODE_PROXY_USER}-session-blogpuppeteer01-lifetime-10`,
password: process.env.GEONODE_PROXY_PASS,
});We made three requests using the same session:
| Request | IP |
|---|---|
| Request 1 | 178.64.64.40 |
| Request 2 | 178.64.64.40 |
| Request 3 | 178.64.64.40 |
Same IP: Yes
All three requests used the same IP.
See the Geonode guides for rotating proxies and sticky sessions for the available settings.
Common proxy errors in Puppeteer and how to fix them
If the proxy is not working, start with the connection details. Check the username and password, then the host, port, and protocol. The error returned by Puppeteer can usually help narrow down the problem.
407 Proxy Authentication Required
A 407 usually points to an authentication problem.
When we tested Puppeteer with an incorrect password, the proxy returned:
HTTP status: 407
Authentication error. Please check your authentication settings.Check the username and password first. If they are correct, make sure page.authenticate() is called after creating the page.
ERR_TUNNEL_CONNECTION_FAILED / connection refused
A connection error usually means Puppeteer could not reach the proxy.
Check the host and port first. Then make sure the protocol matches the proxy server being used.
In our failed connection test, Puppeteer did not return ERR_TUNNEL_CONNECTION_FAILED. Using an unreachable proxy port returned:
net::ERR_CONNECTION_RESET at http://ip-api.com/jsonThe exact Chromium error can therefore differ depending on how the connection fails.
Timeouts and empty responses
A timeout means the page did not receive a response within the configured time.
First, check whether the target URL works and whether the proxy can connect. If both are working, check the timeout passed to page.goto().
For our test, we used a non-routable proxy with a five-second timeout:
await page.goto(url, {
timeout: 5000,
});Puppeteer returned:
TimeoutError: Navigation timeout of 5000 ms exceededSetting an explicit timeout can help a script fail quickly when the proxy connection hangs.
ERR_NO_SUPPORTED_PROXIES
One Puppeteer-specific problem we found was putting the username and password directly inside --proxy-server.
This configuration failed:
--proxy-server=http://USERNAME:PASSWORD@proxy.geonode.io:9000Puppeteer returned:
net::ERR_NO_SUPPORTED_PROXIESThe fix is to pass only the proxy server through the launch argument:
args: ["--proxy-server=http://proxy.geonode.io:9000"]Then authenticate separately:
await page.authenticate({
username: process.env.GEONODE_PROXY_USER,
password: process.env.GEONODE_PROXY_PASS,
});After changing the setup, the request succeeded with HTTP 200.
Puppeteer + Geonode: what you get
Puppeteer handles the requests or connections in the application. Geonode handles the proxy connection.
You can choose residential, ISP, or datacenter proxies based on the job, then use rotation, sticky sessions, and geo-targeting where needed. This keeps the proxy setup separate from the rest of the application code.
Plans vary by proxy type, with some options priced per GB.
FAQ
If you encounter any issues, refer to the troubleshooting section or Geonode support.
Was this page helpful?