decolua/9router · error · Error

Failed to uninstall certificate: ${e.message}

Error message

Failed to uninstall certificate: ${e.message}

What it means

uninstallCertWindows() runs `certutil -delstore Root <CN>` via an auto-elevating PowerShell (UAC). Any failure from the elevated run is rethrown as `Failed to uninstall certificate: <detail>`. It wraps UAC denial, non-admin context, and certutil non-zero exits.

Source

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

async function uninstallCertMac(sudoPassword, certPath) {
  const fingerprint = getCertFingerprint(certPath).replace(/:/g, "");
  const command = `security delete-certificate -Z "${fingerprint}" /Library/Keychains/System.keychain`;
  try {
    await execWithPassword(command, sudoPassword);
    log("🔐 Cert: ✅ uninstalled from system keychain");
  } catch (err) {
    throw new Error("Failed to uninstall certificate");
  }
}

async function uninstallCertWindows() {
  // Auto-elevate via UAC popup if not admin
  const script = `certutil -delstore Root ${quotePs(ROOT_CA_CN)}`;
  try {
    await runElevatedPowerShell(script);
    log("🔐 Cert: ✅ uninstalled from Windows Root store");
  } catch (e) {
    throw new Error(`Failed to uninstall certificate: ${e.message}`);
  }
}

function checkCertInstalledLinux() {
  const config = getLinuxCertConfig();
  const certFile = `${config.dir}/9router-root-ca.crt`;
  return Promise.resolve(fs.existsSync(certFile));
}

async function updateNssDatabases(certPath, action = 'add') {
  const certName = "9Router MITM Root CA";
  
  const script = `
    if ! command -v certutil &> /dev/null; then
      exit 0
    fi
    
    DIRS="$HOME/.pki/nssdb $HOME/snap/chromium/current/.pki/nssdb"

View on GitHub (pinned to 90b52e06ff)

Solutions

  1. Accept the UAC prompt or run once as Administrator
  2. Verify the cert exists: `certutil -store Root <CN>` in an admin shell
  3. Manually run `certutil -delstore Root <CN>` to see the raw error
  4. If ROOT_CA_CN was renamed, uninstall using the original CN
Defensive patterns

Strategy: try-catch

Validate before calling

const installed = await checkCertInstalled(certPath);
if (!installed) return; // nothing to remove
// warn if not elevated
const isAdmin = (await exec('net session').catch(() => null)) !== null;
if (!isAdmin) console.warn('UAC prompt required for cert uninstall');

Try / catch

try {
  await uninstallCert(sudoPassword, certPath);
} catch (e) {
  if (e.message.startsWith('Failed to uninstall certificate:')) {
    console.error('certutil delstore failed:', e.message);
    // fallback: manual `certutil -delstore Root <CN>` as admin
  } else throw e;
}

Prevention

When it happens

Trigger: uninstallCert() on Windows when: user declines UAC, elevation fails in non-interactive sessions, certutil -delstore exits non-zero, or the CN quoting (quotePs of ROOT_CA_CN) does not match the installed cert.

Common situations: Headless/CI Windows where UAC prompts cannot be shown; cert already deleted by hand so delstore errors; ROOT_CA_CN changed in a version update so the old CN no longer matches; AV blocking certutil.

Understand the failure class

Related errors


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