{"record":{"id":"6211bef654b2acf8","repo":"microsoft/playwright","slug":"pfx-is-specified-together-with-cert-key-or-passph","errorCode":null,"errorMessage":"pfx is specified together with cert, key or passphrase","messagePattern":"pfx is specified together with cert, key or passphrase","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/playwright-core/src/server/browserContext.ts","lineNumber":808,"sourceCode":"    throw new Error(`geolocation.latitude: precondition -90 <= LATITUDE <= 90 failed.`);\n  if (accuracy < 0)\n    throw new Error(`geolocation.accuracy: precondition 0 <= ACCURACY failed.`);\n}\n\nexport function verifyClientCertificates(clientCertificates?: types.BrowserContextOptions['clientCertificates']) {\n  if (!clientCertificates)\n    return;\n  for (const cert of clientCertificates) {\n    if (!cert.origin)\n      throw new Error(`clientCertificates.origin is required`);\n    if (!cert.cert && !cert.key && !cert.passphrase && !cert.pfx)\n      throw new Error('None of cert, key, passphrase or pfx is specified');\n    if (cert.cert && !cert.key)\n      throw new Error('cert is specified without key');\n    if (!cert.cert && cert.key)\n      throw new Error('key is specified without cert');\n    if (cert.pfx && (cert.cert || cert.key))\n      throw new Error('pfx is specified together with cert, key or passphrase');\n  }\n}\n\nexport function normalizeProxySettings(proxy: types.ProxySettings): types.ProxySettings {\n  let { server, bypass } = proxy;\n  let url;\n  try {\n    // new URL('127.0.0.1:8080') throws\n    // new URL('localhost:8080') fails to parse host or protocol\n    // In both of these cases, we need to try re-parse URL with `http://` prefix.\n    url = new URL(server);\n    if (!url.host || !url.protocol)\n      url = new URL('http://' + server);\n  } catch (e) {\n    url = new URL('http://' + server);\n  }\n  if (url.protocol === 'socks4:' && (proxy.username || proxy.password))\n    throw new Error(`Socks4 proxy protocol does not support authentication`);","sourceCodeStart":790,"sourceCodeEnd":826,"githubUrl":"https://github.com/microsoft/playwright/blob/c8fc3bf8d31542d59b4d4d9eaab1df93ff541dc6/packages/playwright-core/src/server/browserContext.ts#L790-L826","documentation":"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.)","triggerScenarios":"browser.newContext({ clientCertificates: [{ origin, pfx: <Buffer>, cert: <Buffer> /* or key */ }] }) — mixing the pfx bundle with raw cert/key fields.","commonSituations":"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.","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."],"exampleFix":"// before\nclientCertificates: [{ origin, pfx: fs.readFileSync('bundle.pfx'), cert: fs.readFileSync('client.crt') }]\n// after\nclientCertificates: [{ origin, pfx: fs.readFileSync('bundle.pfx'), passphrase: 'secret' }]","handlingStrategy":"validation","validationCode":"function validateNoPfxMix(certs?: ClientCertificate[]) {\n  for (const c of certs || []) {\n    if (c.pfx && (c.cert || c.key))\n      throw new Error(`pfx mixed with cert/key for ${c.origin}; pick one form`);\n  }\n}","typeGuard":"function usesSingleCertForm(c: ClientCertificate): boolean {\n  const pem = !!(c.cert || c.key);\n  return !(c.pfx && pem);\n}","tryCatchPattern":null,"preventionTips":["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."],"tags":["client-certificates","tls","validation"],"backgroundTag":null,"analyzedSha":"c8fc3bf8d31542d59b4d4d9eaab1df93ff541dc6","analyzedAt":"2026-08-12T07:26:36.950Z","schemaVersion":2},"datasetVersion":"2026-08-12T13:17:24.610Z"}