microsoft/playwright · error · Error
None of cert, key, passphrase or pfx is specified
Error message
None of cert, key, passphrase or pfx is specified
What it means
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.
Source
Thrown at packages/playwright-core/src/server/browserContext.ts:802
return;
geolocation.accuracy = geolocation.accuracy || 0;
const { longitude, latitude, accuracy } = geolocation;
if (longitude < -180 || longitude > 180)
throw new Error(`geolocation.longitude: precondition -180 <= LONGITUDE <= 180 failed.`);
if (latitude < -90 || latitude > 90)
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)View on GitHub (pinned to c8fc3bf8d3)
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.
Example fix
// before
await browser.newContext({
clientCertificates: [{ origin: 'https://example.com' }],
});
// after
import fs from 'fs';
await browser.newContext({
clientCertificates: [{
origin: 'https://example.com',
cert: fs.readFileSync('./client.crt'),
key: fs.readFileSync('./client.key'),
}],
}); Defensive patterns
Strategy: validation
Validate before calling
import type { ClientCertificate } from 'playwright-core';
function validateClientCerts(certs?: ClientCertificate[]) {
if (!certs) return;
for (const c of certs) {
if (!c.origin) throw new Error('clientCertificates.origin is required');
if (!c.cert && !c.key && !c.passphrase && !c.pfx)
throw new Error(`No cert material for ${c.origin}: provide cert+key, or pfx (+passphrase)`);
}
}
// call before browser.newContext / APIRequestContext.newContext Type guard
function hasCertMaterial(c: ClientCertificate): boolean {
return !!(c.cert || c.key || c.passphrase || c.pfx);
} Prevention
- 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.
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- clientCertificates.origin is required
- cert is specified without key
- key is specified without cert
- pfx is specified together with cert, key or passphrase
- "deviceScaleFactor" option is not supported with null "viewp
AI-assisted analysis of microsoft/playwright@c8fc3bf8d3 (2026-08-12).
Data as JSON: /api/errors/9970ba84d22b0ab9.
Report an issue: GitHub.