usebruno/bruno · error · Error
Error reading cert/key file
Error message
Error reading cert/key file
What it means
While building the HTTPS agent for a client-certificate request, Bruno interpolates certFilePath/keyFilePath, resolves them (absolute or relative to the collection), and `fs.readFileSync`s both. Any failure - ENOENT, EACCES, EISDIR, or interpolation producing a non-string - is caught and re-thrown as 'Error reading cert/key file' plus the appended original err.
Source
Thrown at packages/bruno-electron/src/ipc/network/cert-utils.js:95
const domain = interpolateString(clientCert?.domain, interpolationOptions);
const type = clientCert?.type || 'cert';
if (domain) {
const hostRegex = '^(https:\\/\\/|grpc:\\/\\/|grpcs:\\/\\/|ws:\\/\\/|wss:\\/\\/)?'
+ domain.replaceAll('.', '\\.').replaceAll('*', '.*');
const requestUrl = interpolateString(request.url, interpolationOptions);
if (requestUrl && requestUrl.match(hostRegex)) {
if (type === 'cert') {
try {
let certFilePath = interpolateString(clientCert?.certFilePath, interpolationOptions);
certFilePath = path.isAbsolute(certFilePath) ? certFilePath : path.join(collectionPath, certFilePath);
let keyFilePath = interpolateString(clientCert?.keyFilePath, interpolationOptions);
keyFilePath = path.isAbsolute(keyFilePath) ? keyFilePath : path.join(collectionPath, keyFilePath);
httpsAgentRequestFields['cert'] = fs.readFileSync(certFilePath);
httpsAgentRequestFields['key'] = fs.readFileSync(keyFilePath);
} catch (err) {
console.error('Error reading cert/key file', err);
throw new Error('Error reading cert/key file' + err);
}
} else if (type === 'pfx') {
try {
let pfxFilePath = interpolateString(clientCert?.pfxFilePath, interpolationOptions);
pfxFilePath = path.isAbsolute(pfxFilePath) ? pfxFilePath : path.join(collectionPath, pfxFilePath);
httpsAgentRequestFields['pfx'] = fs.readFileSync(pfxFilePath);
} catch (err) {
console.error('Error reading pfx file', err);
throw new Error('Error reading pfx file' + err);
}
}
httpsAgentRequestFields['passphrase'] = interpolateString(clientCert.passphrase, interpolationOptions);
break;
}
}
}
/**View on GitHub (pinned to 9bdd81c7bd)
Solutions
- Read the appended original error (ENOENT vs EACCES) - it tells you which file and why.
- Verify both certFilePath and keyFilePath exist at the resolved location and are readable.
- If the path uses interpolation, confirm the variable resolves to a non-empty string.
- Use an absolute path to remove ambiguity, or ensure a relative path is relative to the collection dir.
Example fix
// before - env var unset, path becomes '.../undefined/client.crt'
certFilePath: "{{certsDir}}/client.crt"
// after - set the var, or use an absolute path
certFilePath: "/etc/bruno-certs/client.crt" Defensive patterns
Strategy: try-catch
Validate before calling
const fs = require('fs');
const certPathsReadable = (certFilePath, keyFilePath) => {
for (const p of [certFilePath, keyFilePath]) {
if (!p || typeof p !== 'string') return false;
try { fs.accessSync(p, fs.constants.R_OK); } catch { return false; }
}
return true;
}; Try / catch
try {
await sendRequestWithClientCert(req);
} catch (e) {
if (/reading cert\/key file/i.test(e.message)) {
// inspect the appended original error for which file and the errno (ENOENT/EACCES)
}
} Prevention
- Store certs inside the collection directory and reference them relatively.
- Validate that interpolated path variables resolve to non-empty strings before sending.
- Ensure Bruno has read permission on the cert/key files.
- Prefer absolute cert paths in CI environments.
When it happens
Trigger: The configured cert/key path doesn't exist; the file exists but Bruno lacks read permission; interpolation of a variable in the path yielded undefined so `path.join(collectionPath, undefined)` produced an invalid path; the path points to a directory; a relative path resolved against the wrong collection root.
Common situations: Moving a collection without moving the certs; an env var referenced in the path isn't set; a Windows path on Linux or vice versa; permission changes after a system update.
Related errors
- Invalid system https_proxy "${https_proxy}": ${error.message
- Invalid system https_proxy
- Failed to export ${environmentType} environments.
- Failed to process ${parsedFile.fileName}: ${err.message}
- Failed to parse the file – ensure it is valid JSON or YAML
AI-assisted analysis of usebruno/bruno@9bdd81c7bd (2026-08-13).
Data as JSON: /api/errors/3c78f858d0dc9327.
Report an issue: GitHub.