nikivdev/code · error

kill command exited with status {}

Error message

kill command exited with status {}

What it means

terminate_process on Unix invokes `kill` (and optionally a process-group kill) on the daemon PID; if neither kill invocation reports success it bails with `kill command exited with status <code>`. This means the OS refused or failed to terminate the process (most often because it no longer exists or the caller lacks permission).

Source

Thrown at src/daemon.rs:684

        // First try to kill the process group (negative PID)
        // This ensures child processes are also terminated
        let pgid_kill = Command::new("kill")
            .arg(format!("-{pid}"))
            .stderr(std::process::Stdio::null())
            .status();

        // Also kill the process directly
        let status = Command::new("kill")
            .arg(format!("{pid}"))
            .stderr(std::process::Stdio::null())
            .status()
            .context("failed to invoke kill command")?;

        // If either succeeded, we're good
        if status.success() || pgid_kill.map(|s| s.success()).unwrap_or(false) {
            return Ok(());
        }
        bail!(
            "kill command exited with status {}",
            status.code().unwrap_or(-1)
        );
    }

    #[cfg(windows)]
    {
        let status = Command::new("taskkill")
            .args(["/PID", &pid.to_string(), "/F", "/T"]) // /T kills child processes too
            .status()
            .context("failed to invoke taskkill")?;
        if status.success() {
            return Ok(());
        }
        bail!(
            "taskkill exited with status {}",
            status.code().unwrap_or(-1)
        );

View on GitHub (pinned to a747e741ae)

Solutions

  1. Check the process still exists (`ps -p <pid>`); delete/refresh the stale PID file and retry.
  2. Re-run with elevated privileges (sudo) if the daemon runs as another user.
  3. Verify ownership: only kill processes you own or via the service manager (`systemctl stop ...`).
  4. Recreate the scenario: restart the daemon normally so stop/restart uses a live PID.

Example fix

// before: blindly trusting PID file
terminate_process(pid)?;
// after: verify PID is alive and owned by us first
if process_alive_and_owned(pid) { terminate_process(pid)?; } else { remove_stale_pidfile(); }
Defensive patterns

Strategy: try-catch

Validate before calling

// Rust: verify the PID is alive before attempting a kill
fn pid_alive(pid: i32) -> bool {
    std::path::Path::new(&format!("/proc/{pid}")).exists()
}

Try / catch

match terminate_process(pid) {
    Ok(()) => println!("daemon stopped"),
    Err(e) if e.to_string().contains("kill command exited") => {
        eprintln!("Could not kill pid {pid} — it may already be dead or owned by another user; check `ps -p {pid}` and try sudo.");
        cleanup_stale_pidfile();
    }
    Err(e) => return Err(e),
}

Prevention

When it happens

Trigger: stop_daemon_with_path, start_daemon_inner (restart), or kill_process_on_port calling terminate_process when the target PID is already dead (ESRCH surfaces as non-zero exit), the process belongs to another user, or the PID was recycled by an unrelated process in a different session.

Common situations: Stopping a daemon that already crashed; stale PID file pointing at a dead or reused PID; trying to kill a daemon started by another user or under systemd without privileges; container environments lacking CAP_KILL.

Related errors


AI-assisted analysis of nikivdev/code@a747e741ae (2026-09-01). Data as JSON: /api/errors/6d20064390486059. Report an issue: GitHub.