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
- Generate the root CA first (run the rootCA generate routine) so the cert file exists on disk
- Verify the certPath passed to installCert is the actual on-disk .crt/.pem path
- Check fs.existsSync(certPath) before calling installCert and log the resolved absolute path
- 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
- Always run CA generation as a prerequisite of cert installation
- Log the resolved absolute cert path before installing
- Re-check fs.existsSync after any DATA_DIR or environment change
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
- SSL/TLS and certificate errors — how TLS handshakes and certificate validation fail.
Related errors
- Root CA not found. Generate it first.
- MITM server.js not found at ${effectiveServerPath}. Reinstal
- Root CA not found. Start server first to generate it.
- install finished but package is missing — see install.log
- Installation finished but tailscale.exe not found
AI-assisted analysis of decolua/9router@90b52e06ff (2026-08-30).
Data as JSON: /api/errors/ee7282d0fa833e05.
Report an issue: GitHub.