← Back to microsoft/playwright
microsoft / playwright · Issue No. 42806
1.64.0-next (main @ 07f1a6154); code path unchanged since 1.46
When clientCertificates is set, all context traffic is funneled through Playwright's local SOCKS interceptor (socksClientCertificatesInterceptor.ts), which then has to apply the user's proxy settings itself. It gets two cases wrong.
Case A: launch-level proxy is dropped
const browser = await chromium.launch({ proxy: { server: 'http://my-proxy:3128' } });
const context = await browser.newContext({
clientCertificates: [{ origin: 'https://unrelated.example.com', certPath, keyPath }],
});
const page = await context.newPage();
await page.goto('http://localhost:PORT/empty.html');
Case B: proxy.bypass is ignored
const context = await browser.newContext({
proxy: { server: 'http://my-proxy:3128', bypass: 'localhost' },
clientCertificates: [{ origin: 'https://unrelated.example.com', certPath, keyPath }],
});
const page = await context.newPage();
await page.goto('http://localhost:PORT/empty.html');
Repro using the repo's proxyServer fixture (tests/library), with forwardTo(port, { allowConnectRequests: true }) so CONNECT tunnels are recorded:
| Case | Proxy received |
|---|---|
| launch proxy, no clientCertificates (control) | requestUrls=["http://localhost:PORT/empty.html"] |
| launch proxy + clientCertificates | connectHosts=[] requestUrls=[] (page loaded directly) |
context proxy with bypass: 'localhost', no clientCertificates (control) |
nothing |
| same + clientCertificates | connectHosts=["localhost:PORT"] |
Traffic with clientCertificates follows the same proxy rules as without: a launch-level proxy is used when the context has none, and hosts in proxy.bypass are connected to directly.
bypass list, bypassed hosts are tunneled through the proxy anyway.Both are silent: no error, just wrong routing.
Root cause:
ClientCertificatesProxy only receives the context options (browser.ts newContext), so this._proxy = contextOptions.proxy never sees browser.options.proxy._getProxyAgent() calls createProxyAgent(this._proxy) without a forUrl, and createProxyAgent only evaluates proxy.bypass when a URL is supplied.I intend to work on this and will send a PR.
- Operating System: macOS (Darwin 25.6.0)
- Node.js: 24.8.0
- Browser: Chromium (bundled r1246)
- Playwright: main @ 07f1a6154
Relay reads this issue against the repository's contribution signals: the files it is likely to touch, how the maintainers triage work this size, and what the first contribution would exercise.
The full analysis for this issue is still being assembled. Until then, the description above and the thread on GitHub are the most reliable context.