microsoft/playwright · error · Error
pfx is specified together with cert, key or passphrase
Error message
pfx is specified together with cert, key or passphrase
What it means
Thrown by verifyClientCertificates() when a clientCertificates entry sets pfx together with cert or key. pfx is a self-contained PKCS12 bundle (cert+key+optional passphrase), so combining it with loose cert/key fields is ambiguous and Playwright forbids it. (Note: the message also mentions passphrase, but the actual guard only checks cert || key.)
Source
Thrown at packages/playwright-core/src/server/browserContext.ts:808
throw new Error(`geolocation.latitude: precondition -90 <= LATITUDE <= 90 failed.`);
if (accuracy < 0)
throw new Error(`geolocation.accuracy: precondition 0 <= ACCURACY failed.`);
}
export function verifyClientCertificates(clientCertificates?: types.BrowserContextOptions['clientCertificates']) {
if (!clientCertificates)
return;
for (const cert of clientCertificates) {
if (!cert.origin)
throw new Error(`clientCertificates.origin is required`);
if (!cert.cert && !cert.key && !cert.passphrase && !cert.pfx)
throw new Error('None of cert, key, passphrase or pfx is specified');
if (cert.cert && !cert.key)
throw new Error('cert is specified without key');
if (!cert.cert && cert.key)
throw new Error('key is specified without cert');
if (cert.pfx && (cert.cert || cert.key))
throw new Error('pfx is specified together with cert, key or passphrase');
}
}
export function normalizeProxySettings(proxy: types.ProxySettings): types.ProxySettings {
let { server, bypass } = proxy;
let url;
try {
// new URL('127.0.0.1:8080') throws
// new URL('localhost:8080') fails to parse host or protocol
// In both of these cases, we need to try re-parse URL with `http://` prefix.
url = new URL(server);
if (!url.host || !url.protocol)
url = new URL('http://' + server);
} catch (e) {
url = new URL('http://' + server);
}
if (url.protocol === 'socks4:' && (proxy.username || proxy.password))
throw new Error(`Socks4 proxy protocol does not support authentication`);View on GitHub (pinned to c8fc3bf8d3)
Solutions
- Use pfx alone (plus optional passphrase) and remove cert and key fields.
- Or switch fully to the cert+key PEM form and remove pfx.
- Pick one credential representation per origin entry; do not mix.
Example fix
// before
clientCertificates: [{ origin, pfx: fs.readFileSync('bundle.pfx'), cert: fs.readFileSync('client.crt') }]
// after
clientCertificates: [{ origin, pfx: fs.readFileSync('bundle.pfx'), passphrase: 'secret' }] Defensive patterns
Strategy: validation
Validate before calling
function validateNoPfxMix(certs?: ClientCertificate[]) {
for (const c of certs || []) {
if (c.pfx && (c.cert || c.key))
throw new Error(`pfx mixed with cert/key for ${c.origin}; pick one form`);
}
} Type guard
function usesSingleCertForm(c: ClientCertificate): boolean {
const pem = !!(c.cert || c.key);
return !(c.pfx && pem);
} Prevention
- Standardize on one credential form (PEM or PKCS12) per project and forbid the other in review.
- When migrating PEM -> PFX, delete the cert/key fields in the same commit.
When it happens
Trigger: browser.newContext({ clientCertificates: [{ origin, pfx: <Buffer>, cert: <Buffer> /* or key */ }] }) — mixing the pfx bundle with raw cert/key fields.
Common situations: Developer copies a pfx block and a cert/key block from two examples and merges them. Migrating from PEM to PKCS12 without removing the old cert/key fields.
Related errors
- clientCertificates.origin is required
- None of cert, key, passphrase or pfx is specified
- cert is specified without key
- key is specified without cert
- Invalid input image
AI-assisted analysis of microsoft/playwright@c8fc3bf8d3 (2026-08-12).
Data as JSON: /api/errors/6211bef654b2acf8.
Report an issue: GitHub.