rust-lang/cargo · error · anyhow::Error
probably rustup rustc, but without rustup's env vars
Error message
probably rustup rustc, but without rustup's env vars
What it means
rustc_fingerprint detects that the resolved rustc path equals the rustup shim path (`maybe_rustup` true), meaning the compiler appears to be rustup-managed, but neither `RUSTUP_HOME` nor `RUSTUP_TOOLCHAIN` is set in the environment. Because rustup can swap the real compiler without touching the shim, Cargo cannot reliably fingerprint it without those vars, so it conservatively bails rather than risk a stale cache.
Source
Thrown at src/util/rustc.rs:394
let maybe_rustup = rustup_rustc == rustc;
match (
maybe_rustup,
gctx.get_env("RUSTUP_HOME"),
gctx.get_env("RUSTUP_TOOLCHAIN"),
) {
(_, Ok(rustup_home), Ok(rustup_toolchain)) => {
debug!("adding rustup info to rustc fingerprint");
rustup_toolchain.hash(&mut hasher);
rustup_home.hash(&mut hasher);
let real_rustc = Path::new(&rustup_home)
.join("toolchains")
.join(rustup_toolchain)
.join("bin")
.join("rustc")
.with_extension(env::consts::EXE_EXTENSION);
paths::mtime(&real_rustc)?.hash(&mut hasher);
}
(true, _, _) => anyhow::bail!("probably rustup rustc, but without rustup's env vars"),
_ => (),
}
Ok(Hasher::finish(&hasher))
}
fn process_fingerprint(cmd: &ProcessBuilder, extra_fingerprint: u64) -> u64 {
let mut hasher = StableHasher::new();
extra_fingerprint.hash(&mut hasher);
cmd.get_args().for_each(|arg| arg.hash(&mut hasher));
let mut env = cmd.get_envs().iter().collect::<Vec<_>>();
env.sort_unstable();
env.hash(&mut hasher);
Hasher::finish(&hasher)
}
View on GitHub (pinned to 0e07a15537)
Solutions
- Ensure `RUSTUP_HOME` and `RUSTUP_TOOLCHAIN` are set/forwarded in the environment (rustup normally exports them; run `rustup which rustc` to see expected values).
- Invoke cargo through rustup's normal entrypoint so env is populated, rather than calling the shim directly.
- Pin a direct (non-rustup) rustc via `build.rustc` in config.toml if you must run with a stripped environment.
- Re-run `rustup default <toolchain>` to repair the rustup setup.
Example fix
# before (env stripped)
env -i cargo build
# after (forward rustup env)
export RUSTUP_HOME="$(rustup show home)"
export RUSTUP_TOOLCHAIN="$(rustup show | awk '/Default Toolchain/{print $2}')"
cargo build Defensive patterns
Strategy: fallback
Validate before calling
fn rustup_env_present() -> bool {
std::env::var("RUSTUP_HOME").is_ok() && std::env::var("RUSTUP_TOOLCHAIN").is_ok()
}
// if false, either forward the env or pin build.rustc to a direct binary Type guard
fn looks_like_rustup_rustc(rustc: &std::path::Path, rustup_rustc: &std::path::Path) -> bool {
rustc == rustup_rustc
} Try / catch
// Fallback: if fingerprinting bails on rustup env, re-run with env forwarded
// or pin a non-rustup rustc.
match rustc_fingerprint(...) {
Err(e) if e.to_string().contains("without rustup's env vars") => {
std::env::set_var("RUSTUP_HOME", home);
std::env::set_var("RUSTUP_TOOLCHAIN", tc);
// retry
}
r => r,
} Prevention
- Always forward `RUSTUP_HOME` and `RUSTUP_TOOLCHAIN` in containers/wrappers.
- Invoke cargo through the normal rustup entrypoint, not the bare shim.
- In sanitized envs, pin `build.rustc` to a direct (non-shim) binary.
When it happens
Trigger: Invoking cargo with a rustup-managed rustc on PATH but with rustup's env vars stripped — e.g. running under a sanitized/wrapper environment, a container that cleared env, calling the rustup shim directly without rustup's exported vars, or an IDE/launcher that filtered the environment.
Common situations: Containers/CI images that strip env vars but keep the rustup shim; `env -i` style sanitized runs; a custom launcher that invokes cargo without forwarding rustup's env; rustup installed but invoked through a proxy that drops env.
Related errors
- invalid character `+` in package name: `+{toolchain}` Us
- malformed output when learning about crate-type {} informati
- output of --print={request} missing when learning about targ
- {}: {:?}
- could not find rustup home dir
AI-assisted analysis of rust-lang/cargo@0e07a15537 (2026-08-06).
Data as JSON: /data/errors/5a4c410475cd17bf.json.
Report an issue: GitHub.