{"record":{"id":"ddd21ce926ccf5ed","repo":"usebruno/bruno","slug":"unable-to-load-custom-ca-certificate-err-as-er","errorCode":null,"errorMessage":"Unable to load custom CA certificate: ${(err as Error).message}","messagePattern":"Unable to load custom CA certificate: (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/bruno-requests/src/utils/ca-cert.ts","lineNumber":119,"sourceCode":"\n    let systemCerts: string[] = [];\n    let rootCerts: string[] = [];\n    let customCerts: string[] = [];\n    let nodeExtraCerts: string[] = [];\n\n    // handle user-provided custom CA certificate file with optional default certificates\n    if (caCertFilePath) {\n      // validate custom CA certificate file\n      if (fs.existsSync(caCertFilePath)) {\n        try {\n          const customCert = fs.readFileSync(caCertFilePath, 'utf8');\n          if (customCert && customCert.trim()) {\n            customCerts.push(customCert);\n            caCertificatesCount.custom = customCerts.length;\n          }\n        } catch (err) {\n          console.error(`Failed to read custom CA certificate from ${caCertFilePath}:`, (err as Error).message);\n          throw new Error(`Unable to load custom CA certificate: ${(err as Error).message}`);\n        }\n      } else {\n        throw new Error(`Invalid custom CA certificate path: ${caCertFilePath}`);\n      }\n\n      if (shouldKeepDefaultCerts) {\n        // get system certs\n        systemCerts = getSystemCerts();\n        caCertificatesCount.system = systemCerts.length;\n\n        // get root certs\n        rootCerts = [...tls.rootCertificates];\n        caCertificatesCount.root = rootCerts.length;\n      }\n    } else {\n      // get system certs\n      systemCerts = getSystemCerts();\n      caCertificatesCount.system = systemCerts.length;","sourceCodeStart":101,"sourceCodeEnd":137,"githubUrl":"https://github.com/usebruno/bruno/blob/9bdd81c7bdc57006e5f5ebffb79321a8d979f712/packages/bruno-requests/src/utils/ca-cert.ts#L101-L137","documentation":"getCACertificates fails to read an existing custom CA file. fs.existsSync returned true but fs.readFileSync threw (permissions, EISDIR, EACCES, encoding error), so the loader re-throws wrapped with the underlying message.","triggerScenarios":"caCertFilePath points to a directory or a special file, the process lacks read permission, the file was deleted between the existsSync and readFileSync calls (TOCTOU), or the file is not valid UTF-8.","commonSituations":"Path is a directory, a symlink to a non-readable target, on a network mount with intermittent access, or owned by root while bruno runs as a normal user.","solutions":["Confirm the path is a regular file: fs.statSync(caCertFilePath).isFile().","Fix permissions (chmod 644 / take ownership) so the process can read it.","Point caCertFilePath to a real .pem/.crt file rather than a directory."],"exampleFix":"// before\n{ caCertFilePath: '/etc/ssl/certs' } // directory -> EISDIR -> throws\n\n// after\n{ caCertFilePath: '/etc/ssl/certs/myCA.pem' }","handlingStrategy":"validation","validationCode":"import fs from 'node:fs';\nfunction assertReadableCertFile(p) {\n  if (!p || !fs.existsSync(p)) throw new Error(`Invalid custom CA certificate path: ${p}`);\n  const st = fs.statSync(p);\n  if (!st.isFile()) throw new Error(`Unable to load custom CA certificate: not a file (${p})`);\n  fs.accessSync(p, fs.constants.R_OK);\n}","typeGuard":"function isReadableFile(p): p is string { try { return typeof p==='string' && !!p && fs.statSync(p).isFile() && fs.accessSync(p, fs.constants.R_OK) === undefined; } catch { return false; } }","tryCatchPattern":"try { return getCACertificates({ caCertFilePath }); } catch (e) { if (/Unable to load custom CA certificate/.test(e.message)) { /* disable custom CA, retry with defaults */ } else throw e; }","preventionTips":["Stat the path to confirm it is a regular file before passing it in.","Fix ownership/permissions on cert files used by the process."],"tags":["tls","ca-cert","filesystem","permissions"],"backgroundTag":null,"analyzedSha":"9bdd81c7bdc57006e5f5ebffb79321a8d979f712","analyzedAt":"2026-08-13T04:09:25.751Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}