{"record":{"id":"ed9bf31429a20d1d","repo":"decolua/9router","slug":"root-ca-not-found-generate-it-first","errorCode":null,"errorMessage":"Root CA not found. Generate it first.","messagePattern":"Root CA not found\\. Generate it first\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"src/mitm/cert/rootCA.js","lineNumber":100,"sourceCode":"  cert.sign(keys.privateKey, forge.md.sha256.create());\n\n  // Save to disk\n  const privateKeyPem = forge.pki.privateKeyToPem(keys.privateKey);\n  const certPem = forge.pki.certificateToPem(cert);\n\n  fs.writeFileSync(ROOT_CA_KEY_PATH, privateKeyPem);\n  fs.writeFileSync(ROOT_CA_CERT_PATH, certPem);\n\n  console.log(\"✅ Root CA generated successfully\");\n  return { key: ROOT_CA_KEY_PATH, cert: ROOT_CA_CERT_PATH };\n}\n\n/**\n * Load Root CA from disk\n */\nfunction loadRootCA() {\n  if (!fs.existsSync(ROOT_CA_KEY_PATH) || !fs.existsSync(ROOT_CA_CERT_PATH)) {\n    throw new Error(\"Root CA not found. Generate it first.\");\n  }\n\n  const keyPem = fs.readFileSync(ROOT_CA_KEY_PATH, \"utf8\");\n  const certPem = fs.readFileSync(ROOT_CA_CERT_PATH, \"utf8\");\n\n  return {\n    key: forge.pki.privateKeyFromPem(keyPem),\n    cert: forge.pki.certificateFromPem(certPem)\n  };\n}\n\n/**\n * Generate leaf certificate for a specific domain, signed by Root CA\n */\nfunction generateLeafCert(domain, rootCA) {\n  // Generate key pair for leaf cert\n  const keys = forge.pki.rsa.generateKeyPair(2048);\n","sourceCodeStart":82,"sourceCodeEnd":118,"githubUrl":"https://github.com/decolua/9router/blob/90b52e06ffd666b7929554211474d01588f6b1f8/src/mitm/cert/rootCA.js#L82-L118","documentation":"loadRootCA() reads the root CA key and cert PEM files from disk. If either ROOT_CA_KEY_PATH or ROOT_CA_CERT_PATH does not exist, it throws 'Root CA not found. Generate it first.' The library requires the CA to be generated before any MITM/leaf-cert signing can happen.","triggerScenarios":"Calling rootCA()/loadRootCA() before ever running the CA generation step; after deleting ~/.9router (or DATA_DIR) contents; when DATA_DIR changed between generation and load so the stored paths point elsewhere.","commonSituations":"Fresh install where the setup/generate step was skipped; CI container with an empty data dir; moving the app data directory without migrating files; disk cleanup removing the key/cert files.","solutions":["Generate the root CA (call the library's CA generate routine / run the setup step) then retry","Verify ROOT_CA_KEY_PATH and ROOT_CA_CERT_PATH point to existing files","If DATA_DIR changed, restore the old key/cert files there or regenerate","Back up the generated CA so it survives data-dir cleanup"],"exampleFix":"// before\nconst ca = rootCA(); // throws if not generated\n\n// after\nif (!fs.existsSync(ROOT_CA_KEY_PATH) || !fs.existsSync(ROOT_CA_CERT_PATH)) {\n  generateRootCA();\n}\nconst ca = rootCA();","handlingStrategy":"validation","validationCode":"import fs from 'fs';\nif (!fs.existsSync(ROOT_CA_KEY_PATH) || !fs.existsSync(ROOT_CA_CERT_PATH)) {\n  await generateRootCA(); // or surface a 'run setup first' message\n}","typeGuard":null,"tryCatchPattern":"let ca;\ntry {\n  ca = rootCA();\n} catch (e) {\n  if (e.message.includes('Root CA not found')) {\n    await generateRootCA();\n    ca = rootCA();\n  } else throw e;\n}","preventionTips":["Run the CA generation step as part of first-time setup, before starting MITM","Do not wipe the app data dir (~/.9router) without regenerating the CA","Back up the CA key/cert; keep DATA_DIR stable across restarts"],"tags":["certificate","missing-file","initialization"],"backgroundTag":"root-ca-not-found","analyzedSha":"90b52e06ffd666b7929554211474d01588f6b1f8","analyzedAt":"2026-08-30T21:05:45.952Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}