rust-lang/rust · critical

Failed to spawn cargo: {}

Error message

Failed to spawn cargo: {}

What it means

Panics in the cargo-clif launcher shim when Command::exec() (unix exec replacement) fails to replace the process with cargo. cargo-clif assembles RUSTFLAGS/RUSTDOCFLAGS pointing rustc at the cranelift codegen backend and then replaces itself with cargo; exec failure means the toolchain cargo binary could not be started.

Source

Thrown at compiler/rustc_codegen_cranelift/scripts/cargo-clif.rs:84

    rustflags_to_cmd_env(
        &mut cmd,
        "RUSTFLAGS",
        &rustflags_from_env("RUSTFLAGS")
            .into_iter()
            .chain(rustflags.iter().map(|flag| flag.clone()))
            .collect::<Vec<_>>(),
    );
    rustflags_to_cmd_env(
        &mut cmd,
        "RUSTDOCFLAGS",
        &rustflags_from_env("RUSTDOCFLAGS")
            .into_iter()
            .chain(rustflags.iter().map(|flag| flag.clone()))
            .collect::<Vec<_>>(),
    );

    #[cfg(unix)]
    panic!("Failed to spawn cargo: {}", cmd.exec());

    #[cfg(not(unix))]
    std::process::exit(cmd.spawn().unwrap().wait().unwrap().code().unwrap_or(1));
}

View on GitHub (pinned to 22057b88b0)

Solutions

  1. Run `rustup toolchain list` and confirm the toolchain named at build time is installed; install it if missing.
  2. Run `which cargo` / `$CARGO --version` in the same shell to confirm the binary exists and is executable.
  3. Re-run `./y.rs prepare` so the toolchain is downloaded and the scripts know TOOLCHAIN_NAME.
  4. If invoking cargo-clif manually, source the env setup emitted by the build instead of relying on ambient PATH.

Example fix

// before
#[cfg(unix)]
panic!("Failed to spawn cargo: {}", cmd.exec());
// after
#[cfg(unix)]
{
    let cargo = env::var_os("CARGO").unwrap_or_else(|| "cargo".into());
    eprintln!("cargo-clif: exec {:?} via {:?}", cargo, std::env::var("RUSTUP_TOOLCHAIN").ok());
    panic!("Failed to spawn cargo: {}", cmd.exec());
}
Defensive patterns

Strategy: validation

Validate before calling

fn ensure_tool(name: &str) -> Result<(), String> {
    if std::process::Command::new(name).arg("--version").output().is_err() {
        if let Err(_) = which::which(name) {
            return Err(format!("{} not found on PATH; install the rust toolchain / set RUSTUP_HOME", name));
        }
    }
    Ok(())
}
// call ensure_tool("cargo") before invoking cargo-clif

Type guard

fn cargo_available() -> bool {
    std::process::Command::new("cargo").arg("--version").status().is_ok()
}

Try / catch

use std::panic;
let r = panic::catch_unwind(|| Command::new("cargo").args(args).status());
if r.is_err() { eprintln!("cargo could not be spawned; check PATH/RUSTUP_HOME"); std::process::exit(1); }

Prevention

When it happens

Trigger: Reached only on unix at the end of cargo-clif.rs after building the cargo Command and setting RUSTFLAGS/RUSTDOCFLAGS. CommandExt::exec returns the io::Error only when the spawn/exec syscall itself fails (the cargo binary could not be executed); it does NOT report cargo's exit code.

Common situations: cargo binary not on PATH or the CARGO env var points at a nonexistent/unexecutable path; rustup toolchain named by TOOLCHAIN_NAME is not installed (`rustup toolchain list`); the resolved cargo is not executable (chmod, broken rustup install, truncated download); PATH corrupted inside a wrapper script; attempting to run cargo-clif outside the rustbuild/rustup environment it was built for.

Related errors


AI-assisted analysis of rust-lang/rust@22057b88b0 (2026-08-03). Data as JSON: /data/errors/0c3bd43dcc4b16b9.json. Report an issue: GitHub.