usebruno/bruno · error · Error

Error reading cert/key file: ${err.message}

Error message

Error reading cert/key file: ${err.message}

What it means

Catch-all around the cert/key loading block. Wraps any thrown error — including the required-field guards above and fs.readFileSync failures (ENOENT, EACCES, EISDIR) — with the 'Error reading cert/key file:' prefix.

Source

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

      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) {
            console.error('Error reading pfx file', err);
            throw new Error(`Error reading pfx file: ${err.message}`);
          }
        }
        certsConfig.passphrase = clientCert.passphrase;
        break;
      }
    }

View on GitHub (pinned to 9bdd81c7bd)

Solutions

  1. Read the suffix to separate missing-file (ENOENT) from missing-config ('... is required for cert type').
  2. Confirm certFilePath and keyFilePath are absolute or correctly relative to collectionPath.
  3. Re-pick both files in the Client Certificates UI after moving the collection.

Example fix

// before: only cert was set, key path stale -> 'Error reading cert/key file: ENOENT'
{ certFilePath:'/old/c.pem', keyFilePath:'/old/k.pem' }

// after
{ certFilePath:'/new/c.pem', keyFilePath:'/new/k.pem' }
Defensive patterns

Strategy: try-catch

Validate before calling

import fs from 'node:fs';
for (const cc of certs) {
  if (cc.disabled || cc.type === 'pfx') continue;
  for (const p of [cc.certFilePath, cc.keyFilePath]) {
    if (!p) continue;
    const full = path.isAbsolute(p) ? p : path.join(collectionPath, p);
    if (!fs.existsSync(full)) throw new Error(`cert/key file not found: ${full}`);
  }
}

Try / catch

try { configureCert(certsConfig, ...); } catch (e) { if (/Error reading cert\/key file/.test(e.message)) { /* disable cert, retry without it */ } else throw e; }

Prevention

When it happens

Trigger: certFilePath/keyFilePath resolved to a missing/unreadable file, OR one of the required-field guards fired (in which case the suffix is itself 'certFilePath is required for cert type' etc.).

Common situations: Cert/key paths stored relative but resolved against an unexpected collectionPath; file moved or deleted; collection shared across machines with different absolute paths; the required-field message surfaces here because the try wraps the guards too.

Related errors


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