decolua/9router · error · Error
User canceled authorization | Certificate install failed
Error message
User canceled authorization | Certificate install failed
What it means
installCertMac() runs `security add-trusted-cert -d -r trustRoot -k /Library/Keychains/System.keychain` via execWithPassword (sudo). If the command exits non-zero, the error is normalized: 'User canceled authorization' when the underlying error mentions 'canceled' (user dismissed the sudo/auth prompt), otherwise the generic 'Certificate install failed'.
Source
Thrown at src/mitm/cert/install.js:115
if (IS_WIN) {
await installCertWindows(certPath);
} else if (IS_MAC) {
await installCertMac(sudoPassword, certPath);
} else {
await installCertLinux(sudoPassword, certPath);
}
}
async function installCertMac(sudoPassword, certPath) {
// Remove all old certs with same name first to avoid duplicate/stale cert conflict
const deleteOld = `security delete-certificate -c "9Router MITM Root CA" /Library/Keychains/System.keychain 2>/dev/null || true`;
const install = `security add-trusted-cert -d -r trustRoot -k /Library/Keychains/System.keychain "${certPath}"`;
try {
await execWithPassword(`${deleteOld} && ${install}`, sudoPassword);
log("🔐 Cert: ✅ installed to system keychain");
} catch (error) {
const msg = error.message?.includes("canceled") ? "User canceled authorization" : "Certificate install failed";
throw new Error(msg);
}
}
async function installCertWindows(certPath) {
// Auto-elevate via UAC popup if not admin (zero popup if already admin).
// Delete any stale cert with same CN before adding to avoid duplicates.
const script = `
certutil -delstore Root ${quotePs(ROOT_CA_CN)} 2>$null | Out-Null
$exit = & certutil -addstore Root ${quotePs(certPath)} 2>&1
if ($LASTEXITCODE -ne 0) { throw "certutil exit $LASTEXITCODE" }
`;
try {
await runElevatedPowerShell(script);
log("🔐 Cert: ✅ installed to Windows Root store");
} catch (e) {
throw new Error(`Failed to install certificate: ${e.message}`);
}
}View on GitHub (pinned to 90b52e06ff)
Solutions
- Re-run the install and accept the authorization dialog when it appears
- Verify the sudo password is correct by testing `sudo -v` in a terminal
- Check MDM/security policy allows adding trustRoot certs to the System keychain
- Manually run `security add-trusted-cert -d -r trustRoot -k /Library/Keychains/System.keychain <cert>` to see the raw error
Defensive patterns
Strategy: try-catch
Validate before calling
// Pre-check cert exists and macOS is not under a policy that blocks keychain writes is not directly queryable;
// at minimum verify the binary and cert:
await exec('which security');
if (!fs.existsSync(certPath)) throw new Error('cert missing before macOS install'); Try / catch
try {
await installCert(sudoPassword, certPath);
} catch (e) {
if (e.message === 'User canceled authorization') {
// prompt user to retry and accept the dialog
} else if (e.message === 'Certificate install failed') {
// fall back to manual instructions
} else throw e;
} Prevention
- Surface a clear UI prompt before triggering the sudo dialog so the user expects it
- Retry once automatically on 'User canceled authorization'
- Document the manual `security add-trusted-cert` command as a fallback
When it happens
Trigger: installCert() on macOS when: the user dismisses/cancels the sudo password dialog, the sudo password is wrong, `security add-trusted-cert` rejects the cert, or the System.keychain is locked/unwritable.
Common situations: User walks away from the auth dialog and it times out or is dismissed; wrong sudo password typed into the prompt; corporate-managed Macs with MDM restrictions blocking trustRoot insertion; macOS security-policy changes requiring interactive approval of root certs.
Understand the failure class
- SSL/TLS and certificate errors — how TLS handshakes and certificate validation fail.
Related errors
- Failed to uninstall certificate
- Certificate install failed: ${error.message}
- Sudo password required to install Root CA certificate
- Failed to trust certificate: ${e.message}
- Sudo password required to trust certificate
AI-assisted analysis of decolua/9router@90b52e06ff (2026-08-30).
Data as JSON: /api/errors/f83466954f8eb84f.
Report an issue: GitHub.