decolua/9router · error · Error

Root CA not found. Generate it first.

Error message

Root CA not found. Generate it first.

What it means

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.

Source

Thrown at src/mitm/cert/rootCA.js:100

  cert.sign(keys.privateKey, forge.md.sha256.create());

  // Save to disk
  const privateKeyPem = forge.pki.privateKeyToPem(keys.privateKey);
  const certPem = forge.pki.certificateToPem(cert);

  fs.writeFileSync(ROOT_CA_KEY_PATH, privateKeyPem);
  fs.writeFileSync(ROOT_CA_CERT_PATH, certPem);

  console.log("✅ Root CA generated successfully");
  return { key: ROOT_CA_KEY_PATH, cert: ROOT_CA_CERT_PATH };
}

/**
 * Load Root CA from disk
 */
function loadRootCA() {
  if (!fs.existsSync(ROOT_CA_KEY_PATH) || !fs.existsSync(ROOT_CA_CERT_PATH)) {
    throw new Error("Root CA not found. Generate it first.");
  }

  const keyPem = fs.readFileSync(ROOT_CA_KEY_PATH, "utf8");
  const certPem = fs.readFileSync(ROOT_CA_CERT_PATH, "utf8");

  return {
    key: forge.pki.privateKeyFromPem(keyPem),
    cert: forge.pki.certificateFromPem(certPem)
  };
}

/**
 * Generate leaf certificate for a specific domain, signed by Root CA
 */
function generateLeafCert(domain, rootCA) {
  // Generate key pair for leaf cert
  const keys = forge.pki.rsa.generateKeyPair(2048);

View on GitHub (pinned to 90b52e06ff)

Solutions

  1. Generate the root CA (call the library's CA generate routine / run the setup step) then retry
  2. Verify ROOT_CA_KEY_PATH and ROOT_CA_CERT_PATH point to existing files
  3. If DATA_DIR changed, restore the old key/cert files there or regenerate
  4. Back up the generated CA so it survives data-dir cleanup

Example fix

// before
const ca = rootCA(); // throws if not generated

// after
if (!fs.existsSync(ROOT_CA_KEY_PATH) || !fs.existsSync(ROOT_CA_CERT_PATH)) {
  generateRootCA();
}
const ca = rootCA();
Defensive patterns

Strategy: validation

Validate before calling

import fs from 'fs';
if (!fs.existsSync(ROOT_CA_KEY_PATH) || !fs.existsSync(ROOT_CA_CERT_PATH)) {
  await generateRootCA(); // or surface a 'run setup first' message
}

Try / catch

let ca;
try {
  ca = rootCA();
} catch (e) {
  if (e.message.includes('Root CA not found')) {
    await generateRootCA();
    ca = rootCA();
  } else throw e;
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of decolua/9router@90b52e06ff (2026-08-30). Data as JSON: /api/errors/ed9bf31429a20d1d. Report an issue: GitHub.