usebruno/bruno · error · Error

keyFilePath is required for cert type

Error message

keyFilePath is required for cert type

What it means

Counterpart to the cert-file guard: a type 'cert' entry requires keyFilePath to be set. Throws when certFilePath was provided but keyFilePath is falsy.

Source

Thrown at packages/bruno-requests/src/utils/http-https-agents.ts:289

  for (const clientCert of clientCertConfig) {
    if (clientCert?.disabled) {
      continue;
    }
    const domain = clientCert?.domain;
    const type = clientCert?.type || 'cert';
    if (domain) {
      const hostRegex = '^(https:\\/\\/|grpc:\\/\\/|grpcs:\\/\\/)?' + domain.replace(/\./g, '\\.').replace(/\*/g, '.*');
      if (requestUrl && requestUrl.match(hostRegex)) {
        if (type === 'cert') {
          try {
            let certFilePath = clientCert?.certFilePath;
            if (!certFilePath) {
              throw new Error('certFilePath is required for cert type');
            }
            certFilePath = path.isAbsolute(certFilePath) ? certFilePath : path.join(collectionPath, certFilePath);
            let keyFilePath = clientCert?.keyFilePath;
            if (!keyFilePath) {
              throw new Error('keyFilePath is required for cert type');
            }
            keyFilePath = path.isAbsolute(keyFilePath) ? keyFilePath : path.join(collectionPath, keyFilePath);

            certsConfig.cert = fs.readFileSync(certFilePath);
            certsConfig.key = fs.readFileSync(keyFilePath);
          } catch (err: any) {
            console.error('Error reading cert/key file', err);
            throw new Error(`Error reading cert/key file: ${err.message}`);
          }
        } else if (type === 'pfx') {
          try {
            let pfxFilePath = clientCert?.pfxFilePath;
            if (!pfxFilePath) {
              throw new Error('pfxFilePath is required for pfx type');
            }
            pfxFilePath = path.isAbsolute(pfxFilePath) ? pfxFilePath : path.join(collectionPath, pfxFilePath);
            certsConfig.pfx = fs.readFileSync(pfxFilePath);
          } catch (err: any) {

View on GitHub (pinned to 9bdd81c7bd)

Solutions

  1. Select a private key file for the entry in Client Certificates settings.
  2. Populate keyFilePath alongside certFilePath in the stored config.
  3. Disable the entry if you do not have a key yet.

Example fix

// before
{ domain:'api.example.com', type:'cert', certFilePath:'/c.pem' } // no keyFilePath

// after
{ domain:'api.example.com', type:'cert', certFilePath:'/c.pem', keyFilePath:'/k.pem' }
Defensive patterns

Strategy: validation

Validate before calling

for (const cc of clientCertificates?.certs ?? []) {
  if (!cc.disabled && cc.type !== 'pfx' && !cc.keyFilePath) throw new Error(`keyFilePath missing for domain ${cc.domain}`);
}

Type guard

function isValidCertEntry(c): boolean { return c?.type === 'pfx' ? !!c.pfxFilePath : !!c?.certFilePath && !!c?.keyFilePath; }

Prevention

When it happens

Trigger: Client-cert entry matched the request domain, type is 'cert', certFilePath present, but keyFilePath is empty/undefined.

Common situations: User picked the certificate but forgot the private key file; config migrated incompletely; only the public cert was supplied.

Related errors


AI-assisted analysis of usebruno/bruno@9bdd81c7bd (2026-08-13). Data as JSON: /api/errors/5a8e22acb4d2580c. Report an issue: GitHub.