{"record":{"id":"3c78f858d0dc9327","repo":"usebruno/bruno","slug":"error-reading-cert-key-file","errorCode":null,"errorMessage":"Error reading cert/key file","messagePattern":"Error reading cert/key file","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/bruno-electron/src/ipc/network/cert-utils.js","lineNumber":95,"sourceCode":"    const domain = interpolateString(clientCert?.domain, interpolationOptions);\n    const type = clientCert?.type || 'cert';\n    if (domain) {\n      const hostRegex = '^(https:\\\\/\\\\/|grpc:\\\\/\\\\/|grpcs:\\\\/\\\\/|ws:\\\\/\\\\/|wss:\\\\/\\\\/)?'\n        + domain.replaceAll('.', '\\\\.').replaceAll('*', '.*');\n      const requestUrl = interpolateString(request.url, interpolationOptions);\n      if (requestUrl && requestUrl.match(hostRegex)) {\n        if (type === 'cert') {\n          try {\n            let certFilePath = interpolateString(clientCert?.certFilePath, interpolationOptions);\n            certFilePath = path.isAbsolute(certFilePath) ? certFilePath : path.join(collectionPath, certFilePath);\n            let keyFilePath = interpolateString(clientCert?.keyFilePath, interpolationOptions);\n            keyFilePath = path.isAbsolute(keyFilePath) ? keyFilePath : path.join(collectionPath, keyFilePath);\n\n            httpsAgentRequestFields['cert'] = fs.readFileSync(certFilePath);\n            httpsAgentRequestFields['key'] = fs.readFileSync(keyFilePath);\n          } catch (err) {\n            console.error('Error reading cert/key file', err);\n            throw new Error('Error reading cert/key file' + err);\n          }\n        } else if (type === 'pfx') {\n          try {\n            let pfxFilePath = interpolateString(clientCert?.pfxFilePath, interpolationOptions);\n            pfxFilePath = path.isAbsolute(pfxFilePath) ? pfxFilePath : path.join(collectionPath, pfxFilePath);\n            httpsAgentRequestFields['pfx'] = fs.readFileSync(pfxFilePath);\n          } catch (err) {\n            console.error('Error reading pfx file', err);\n            throw new Error('Error reading pfx file' + err);\n          }\n        }\n        httpsAgentRequestFields['passphrase'] = interpolateString(clientCert.passphrase, interpolationOptions);\n        break;\n      }\n    }\n  }\n\n  /**","sourceCodeStart":77,"sourceCodeEnd":113,"githubUrl":"https://github.com/usebruno/bruno/blob/9bdd81c7bdc57006e5f5ebffb79321a8d979f712/packages/bruno-electron/src/ipc/network/cert-utils.js#L77-L113","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before - env var unset, path becomes '.../undefined/client.crt'\ncertFilePath: \"{{certsDir}}/client.crt\"\n// after - set the var, or use an absolute path\ncertFilePath: \"/etc/bruno-certs/client.crt\"","handlingStrategy":"try-catch","validationCode":"const fs = require('fs');\nconst certPathsReadable = (certFilePath, keyFilePath) => {\n  for (const p of [certFilePath, keyFilePath]) {\n    if (!p || typeof p !== 'string') return false;\n    try { fs.accessSync(p, fs.constants.R_OK); } catch { return false; }\n  }\n  return true;\n};","typeGuard":null,"tryCatchPattern":"try {\n  await sendRequestWithClientCert(req);\n} catch (e) {\n  if (/reading cert\\/key file/i.test(e.message)) {\n    // inspect the appended original error for which file and the errno (ENOENT/EACCES)\n  }\n}","preventionTips":["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."],"tags":["network","client-certificate","https","filesystem","interpolation"],"backgroundTag":null,"analyzedSha":"9bdd81c7bdc57006e5f5ebffb79321a8d979f712","analyzedAt":"2026-08-13T04:09:25.751Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}