decolua/9router · error · Error

Sudo password required to trust certificate

Error message

Sudo password required to trust certificate

What it means

trustCert() needs elevated privileges to write into the system trust store, and on platforms where a password is mandatory (isSudoPasswordRequired()) it throws when no sudo password could be obtained from the argument, the in-memory cache, or the encrypted store. The earlier isSudoAvailable() guard only covers non-Windows/non-macOS; this check covers the password itself.

Source

Thrown at src/mitm/manager.js:855

  const password = sudoPassword || getCachedPassword() || await loadEncryptedPassword();
  await removeDNSEntry(tool, password);
  await saveDnsToolState(tool, false);
  return { success: true };
}

/**
 * Install Root CA to system trust store (standalone, no server start)
 */
async function trustCert(sudoPassword) {
  const rootCACertPath = path.join(MITM_DIR, "rootCA.crt");
  if (!fs.existsSync(rootCACertPath)) throw new Error("Root CA not found. Start server first to generate it.");
  const { installCert } = require("./cert/install");
  if (!IS_WIN && !IS_MAC && !isSudoAvailable()) {
    log(`🔐 Cert: system trust unavailable (no sudo). Use file: ${rootCACertPath}`);
    return;
  }
  const password = sudoPassword || getCachedPassword() || await loadEncryptedPassword();
  if (!password && isSudoPasswordRequired()) throw new Error("Sudo password required to trust certificate");
  await installCert(password, rootCACertPath);
  if (password) setCachedPassword(password);
}

// Legacy aliases for backward compatibility
const startMitm = startServer;
const stopMitm = stopServer;

module.exports = {
  getMitmStatus,
  startServer,
  stopServer,
  enableToolDNS,
  disableToolDNS,
  trustCert,
  // Legacy
  startMitm,
  stopMitm,

View on GitHub (pinned to 90b52e06ff)

Solutions

  1. Pass the sudo password explicitly: trustCert(process.env.SUDO_PASSWORD) or from user input
  2. Save the password once via the app's credential flow so loadEncryptedPassword() can retrieve it
  3. If not on a system requiring sudo (Windows/macOS paths differ), the guard may not apply — check isSudoPasswordRequired()
  4. On Linux without stored credentials, manually trust rootCA.crt with sudo cp/update-ca-certificates

Example fix

// before
await trustCert(); // no password available
// after
const password = sudoPassword || (await promptForSudoPassword());
if (!password) throw new Error("Cannot trust cert without sudo password");
await trustCert(password);
Defensive patterns

Strategy: validation

Validate before calling

const password = sudoPassword || getCachedPassword() || (await loadEncryptedPassword());
if (!password && isSudoPasswordRequired()) {
  throw new Error("Collect sudo password before calling trustCert");
}
await trustCert(password);

Type guard

function hasSudoCredential(p) { return typeof p === "string" && p.length > 0; }

Try / catch

try {
  await trustCert(sudoPassword);
} catch (err) {
  if (err.message.includes("Sudo password required")) {
    const pw = await promptUserForSudoPassword();
    if (pw) await trustCert(pw);
  } else throw err;
}

Prevention

When it happens

Trigger: Calling trustCert() with no sudoPassword argument when no password is cached and loadEncryptedPassword() returns null/falsy while isSudoPasswordRequired() is true.

Common situations: Fresh install where the user never saved a sudo password; password cache expired; automation calling trustCert() without passing credentials; user previously declined to store the password encrypted.

Understand the failure class

Related errors


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