Playwright Proxy Rotation: Authentication, Contexts and Sessions
Set a Playwright proxy when creating the browser or browser context. For separate authorized jobs that need different endpoints, create and close a context for each job. Keep a single session on a stable route when its workflow requires continuity; changing an IP is not the same as resetting account state.
Before running the code
- Use the proxy object for proxy credentials. httpCredentials is for the destination’s HTTP authentication.
- Playwright’s username/password proxy fields support HTTP authentication; do not assume they add SOCKS5 authentication support.
- Inspect the navigation status and expected content. A browser loading a 403 page is not a successful data collection.
Choose browser-wide or per-context routing
| Configuration | Scope | Use |
|---|---|---|
| chromium.launch({ proxy }) | The launched browser | One intended route for the browser |
| browser.newContext({ proxy }) | The new browser context | Separate routes for separate jobs |
| proxy.username / proxy.password | HTTP proxy authentication | Credentials accepted by the proxy |
| httpCredentials | Destination HTTP authentication | Credentials for the target service |
| storageState | Saved browser authentication state | An authorized account session, handled as a secret |
Playwright’s network guide supports proxy configuration at browser launch or on an individual browser context. The Browser API documents the server, username, password and optional bypass fields.
Use a browser-wide setting when the whole browser should share one route. Use a context setting when separate test jobs need different endpoints. Keep the choice visible in the configuration rather than combining browser flags, environment variables and several wrappers without knowing which one controls the request.
A context isolates browser state; a website can still associate jobs through their account or other signals. A provider may also rotate the exit behind an unchanged endpoint. Record both the configured endpoint identifier and the observed outbound address when investigating a failure.
Use a matching library and browser build
The current Playwright release notes describe version 1.64. The example was checked with Playwright 1.64.0 and its Chromium 156.0.8078.4 build in an isolated environment on October 11, 2026.
In a Node project, install the library and matching browser:
npm install playwright@1.64.0
npx playwright install chromium
Keep the package lock with your project and review later maintenance releases before upgrading a production workflow. If you choose a separately installed Chrome channel, record that browser version too; it is a different test environment from the bundled build.
The checks described here used local proxy fixtures. They establish the example’s authentication, context isolation and error handling. They do not measure a commercial proxy’s performance or a third-party website’s acceptance rate.
Create a context, check its route, and close it
Set PROXY_SERVER, PROXY_USERNAME and PROXY_PASSWORD through your secret manager or process environment. Use a server value such as http://proxy.example:8080, with the real host and port. Keep the credentials in the separate fields rather than embedding them in that server string.
Save the example as check-proxy.cjs:
const { chromium } = require('playwright');
const { isIP } = require('node:net');
async function checkProxy(browser, proxy, target = 'https://api.ipify.org?format=json') {
const context = await browser.newContext({ proxy });
try {
const page = await context.newPage();
const response = await page.goto(target, {
waitUntil: 'domcontentloaded', timeout: 30_000,
});
if (!response || response.status() !== 200) {
throw Object.assign(new Error('Unexpected response'), {
status: response?.status() ?? null,
});
}
const result = JSON.parse(await page.locator('body').innerText());
if (!isIP(result.ip)) throw new Error('Expected an IP response');
return result.ip;
} finally {
await context.close();
}
}
async function main() {
const server = process.env.PROXY_SERVER;
const username = process.env.PROXY_USERNAME;
const password = process.env.PROXY_PASSWORD;
if (!server || !username || !password) throw new Error('Missing proxy configuration');
const browser = await chromium.launch();
try {
console.log('Observed exit:', await checkProxy(browser, { server, username, password }));
} finally {
await browser.close();
}
}
if (require.main === module) main().catch(error => {
console.error('Proxy check failed:', error.name, error.status ?? 'no HTTP status');
process.exitCode = 1;
});
module.exports = { checkProxy };
Run node check-proxy.cjs. The default endpoint is ipify, which observes the address of the test request. That service receives the request; it does not inspect all traffic from the browser.
The finally blocks close the context and browser on either success or failure. The script reports a status when one is available and avoids printing the complete connection configuration. The module export lets you test the same function against an endpoint you control.
Rotate between jobs, with an explicit session boundary
For an authorized test that needs several routes, supply the next endpoint when creating the next context. The example closes each context before returning, so a caller can run one bounded job and then choose another configured proxy. Choose the next endpoint for the job’s requirements; investigate a denial before retrying.
BrowserContext documentation describes isolated, non-persistent contexts. A new context does not inherit the previous context’s cookies unless your code imports state. Conversely, importing the same account state means you are still using that account, even if the endpoint changed.
If one job requires several authenticated steps, retain its context and use the provider’s documented session behavior. Rotating midway through a login, checkout test or challenge can introduce a new variable and break continuity. Finish or stop that job before assigning another route.
Check the provider’s capacity separately from the number of contexts. Creating fifty contexts does not create fifty independent modems, guaranteed public addresses or additional bandwidth. Start with bounded concurrency and measure your own successful workflow rather than inheriting an arbitrary thread count from an example.
Why SOCKS5 credentials can fail
The public proxy options document authentication fields for HTTP proxies. Playwright 1.64.0’s proxy validation code rejects SOCKS5 settings that include a username or password. The local fixture check confirmed that rejection; a successful authenticated Requests SOCKS connection does not establish browser compatibility.
If the service offers a compatible authenticated HTTP endpoint, configure that endpoint. If your environment uses an approved local adapter, verify its protocol and authentication responsibilities before putting a browser behind it. Do not remove required authentication merely to suppress the error.
Our browser proxy guide explains browser-specific limits. The Python Requests guide covers a different client with its own SOCKS dependency and hostname-resolution behavior.
Check the response as well as navigation completion
The Page API reference explains that page.goto() does not throw just because a server returns a valid HTTP error status such as 404 or 500. The example therefore inspects the returned response and validates the expected JSON body. A challenge or deny page must not become a successful empty record.
For your own app, wait for a specific UI condition or expected response after navigation. A quiet network is not evidence that the required business operation succeeded. Capture the status, request time and a redacted screenshot when those observations help reproduce the problem.
A proxy connection error calls for endpoint and authentication checks. A target 401 calls for the target’s credentials. A 429 needs the destination’s retry policy. A platform account notice belongs to its review flow. The IP-ban diagnosis guide gives those failures separate paths.
Do not solve a failed assertion by disabling TLS checks or adding unlimited retries. Keep the failure visible, correct the relevant configuration and repeat the original small test.
Treat saved state and traces as sensitive
Playwright’s authentication guide warns that saved browser state can contain cookies and headers that permit account access. Keep those files out of source control and limit access to the test identities that need them.
Use a separate state file for each authorized account or test role. Review the content of a trace or screenshot before uploading it to an issue tracker or AI tool. A redacted failure record is usually enough to identify whether the problem concerns the proxy, destination login or application behavior.
Deleting a local context does not delete a platform account or reverse its restrictions. Keep that boundary clear when building a rotation scheduler: browser lifecycle and account standing are different systems.
AI browser tools still use a particular runtime
Playwright 1.64 adds page.webmcp and frame.webmcp for testing tools registered through the experimental WebMCP browser API, as described in the release notes. That browser feature does not configure a separate model API client or hosted worker’s network path. Identify where each request is made before applying a proxy setting.
An agent should report an unexpected status or challenge and stop the affected job. Cloudflare’s supported-browser documentation says automated browsers, including Playwright, are unsupported for solving production challenges; test keys are the documented route for testing your own Turnstile integration.
Use the JA4 checker inside the actual browser session if you need a TLS observation. Run the WebRTC test there when that traffic matters. Neither result exposes another service’s private risk score or grants permission to continue a denied operation.
Sources and review scope
Sources reviewed October 11, 2026. This guide reviews primary documentation. Code examples illustrate configuration and error handling. Any local fixture checks are described in the article; they are not live-provider performance benchmarks or guarantees of destination access.
- Playwright: Network and proxy configuration
- Playwright: Browser proxy options
- Playwright: BrowserContext lifecycle and isolation
- Playwright: Page navigation response behavior
- Playwright: Authentication-state security
- Playwright: 1.64 release notes and WebMCP
- Playwright 1.64.0: proxy validation source
- Cloudflare: supported browsers and automation limits
- ipify: Public IP API
Frequently asked questions
Configure another runtime
Use the settings supported by the process making the request, then verify routing and authentication.
Related workflows
Configure a Python HTTP client separately from the browser.
Match authentication and protocol support.
Identify a challenge or site-policy failure.
Inspect the TLS connection from the browser you are testing.
Compare the existing Chromium automation integration.