decolua/9router · error · Error

Certificate file not found: ${certPath}

Error message

Certificate file not found: ${certPath}

What it means

installCert() verifies the SSL certificate file exists on disk with fs.existsSync() before attempting to add it to the system trust store. If the path does not exist, it throws immediately with the offending path in the message. This is a pre-flight guard preventing sudo/powershell commands from running against a missing file.

Source

Thrown at src/mitm/cert/install.js:88

    // Check by SHA1 fingerprint — detects stale cert with same CN but different key
    let fingerprint;
    try {
      fingerprint = getCertFingerprint(certPath).replace(/:/g, "");
    } catch {
      return resolve(false);
    }
    exec(`certutil -store Root ${fingerprint}`, { windowsHide: true }, (error) => {
      resolve(!error);
    });
  });
}

/**
 * Install SSL certificate to system trust store
 */
async function installCert(sudoPassword, certPath) {
  if (!fs.existsSync(certPath)) {
    throw new Error(`Certificate file not found: ${certPath}`);
  }

  const isInstalled = await checkCertInstalled(certPath);
  if (isInstalled) {
    log("🔐 Cert: already trusted ✅");
    return;
  }

  if (IS_WIN) {
    await installCertWindows(certPath);
  } else if (IS_MAC) {
    await installCertMac(sudoPassword, certPath);
  } else {
    await installCertLinux(sudoPassword, certPath);
  }
}

async function installCertMac(sudoPassword, certPath) {

View on GitHub (pinned to 90b52e06ff)

Solutions

  1. Generate the root CA first (run the rootCA generate routine) so the cert file exists on disk
  2. Verify the certPath passed to installCert is the actual on-disk .crt/.pem path
  3. Check fs.existsSync(certPath) before calling installCert and log the resolved absolute path
  4. If the path is derived from config/env (e.g. DATA_DIR), confirm the same value used at generation time

Example fix

// before
await installCert(sudoPassword, certPath);

// after
if (!fs.existsSync(certPath)) {
  await generateRootCA(); // ensure cert exists first
}
await installCert(sudoPassword, certPath);
Defensive patterns

Strategy: validation

Validate before calling

import fs from 'fs';
if (!fs.existsSync(certPath)) {
  throw new Error(`Cannot install: cert file missing at ${certPath}. Generate the CA first.`);
}

Try / catch

try {
  await installCert(sudoPassword, certPath);
} catch (e) {
  if (e.message.startsWith('Certificate file not found')) {
    await generateRootCA();
    await installCert(sudoPassword, certPath);
  } else throw e;
}

Prevention

When it happens

Trigger: Calling installCert(sudoPassword, certPath) where certPath points to a file that does not exist: CA never generated, wrong path passed, cert deleted between generation and install, or path typo.

Common situations: Fresh checkout where 'generate CA' step was skipped; DATA_DIR or ~/.9router moved so stored cert path is stale; running install before rootCA generation completed; passing a relative path from a different working directory.

Understand the failure class

Related errors


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