{"record":{"id":"9970ba84d22b0ab9","repo":"microsoft/playwright","slug":"none-of-cert-key-passphrase-or-pfx-is-specified","errorCode":null,"errorMessage":"None of cert, key, passphrase or pfx is specified","messagePattern":"None of cert, key, passphrase or pfx is specified","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/playwright-core/src/server/browserContext.ts","lineNumber":802,"sourceCode":"    return;\n  geolocation.accuracy = geolocation.accuracy || 0;\n  const { longitude, latitude, accuracy } = geolocation;\n  if (longitude < -180 || longitude > 180)\n    throw new Error(`geolocation.longitude: precondition -180 <= LONGITUDE <= 180 failed.`);\n  if (latitude < -90 || latitude > 90)\n    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)","sourceCodeStart":784,"sourceCodeEnd":820,"githubUrl":"https://github.com/microsoft/playwright/blob/c8fc3bf8d31542d59b4d4d9eaab1df93ff541dc6/packages/playwright-core/src/server/browserContext.ts#L784-L820","documentation":"Thrown by verifyClientCertificates() while validating each entry in context options clientCertificates. A certificate entry must carry real credential material: it throws when an entry has an origin but none of cert, key, passphrase, or pfx is set. Playwright validates up front so the TLS proxy it spins up (ClientCertificatesProxy) does not receive an unusable entry.","triggerScenarios":"Calling browser.newContext({ clientCertificates: [{ origin: 'https://example.com' }] }) — origin supplied but no cert/key/pfx/passphrase fields. Also triggered via APIRequestContext.newContext with the same shape, or launchPersistentContext with clientCertificates.","commonSituations":"Developer adds a clientCertificates entry planning to fill credentials later but forgets. Passing only certPath/keyPath as strings while the validation runs against cert/key Buffer fields before conversion (note: conversion happens earlier in toClientCertificatesProtocol, but a fully empty entry still passes through). Confusing passphrase-only intent.","solutions":["Provide a cert/key pair (cert + key Buffers, or rely on certPath/keyPath which are read into Buffers beforehand) OR a pfx bundle (optionally with passphrase).","Verify the entry shape against the ClientCertificate type: { origin, cert?, key?, pfx?, passphrase? }.","Remove the entry entirely if no credentials are needed for that origin."],"exampleFix":"// before\nawait browser.newContext({\n  clientCertificates: [{ origin: 'https://example.com' }],\n});\n// after\nimport fs from 'fs';\nawait browser.newContext({\n  clientCertificates: [{\n    origin: 'https://example.com',\n    cert: fs.readFileSync('./client.crt'),\n    key: fs.readFileSync('./client.key'),\n  }],\n});","handlingStrategy":"validation","validationCode":"import type { ClientCertificate } from 'playwright-core';\nfunction validateClientCerts(certs?: ClientCertificate[]) {\n  if (!certs) return;\n  for (const c of certs) {\n    if (!c.origin) throw new Error('clientCertificates.origin is required');\n    if (!c.cert && !c.key && !c.passphrase && !c.pfx)\n      throw new Error(`No cert material for ${c.origin}: provide cert+key, or pfx (+passphrase)`);\n  }\n}\n// call before browser.newContext / APIRequestContext.newContext","typeGuard":"function hasCertMaterial(c: ClientCertificate): boolean {\n  return !!(c.cert || c.key || c.passphrase || c.pfx);\n}","tryCatchPattern":null,"preventionTips":["Validate clientCertificates entries against hasCertMaterial before constructing the context.","Always load cert/key/pfx from files with fs.readFileSync inside a try and assert the Buffer is non-empty.","Treat each origin entry as needing either a (cert,key) pair or a (pfx[,passphrase]) bundle — never both."],"tags":["client-certificates","tls","validation","browser-context"],"backgroundTag":null,"analyzedSha":"c8fc3bf8d31542d59b4d4d9eaab1df93ff541dc6","analyzedAt":"2026-08-12T07:26:36.950Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}