rust-lang/cargo · error · anyhow::Error
{}: {:?}
Error message
{}: {:?} What it means
Cache::cached_output captures rustc's stdout as bytes and converts with String::from_utf8; if stdout is not valid UTF-8 it maps the Utf8Error to an anyhow formatting the error and the offending bytes (`{:?}`). The surrounding context notes which rustc command (`{cmd}`) produced the non-UTF-8 output. This typically indicates rustc emitted localized or binary output.
Source
Thrown at src/util/rustc.rs:283
dirty: false,
data: CacheData::default(),
}
}
}
}
fn cached_output(
&mut self,
cmd: &ProcessBuilder,
extra_fingerprint: u64,
) -> CargoResult<(String, String)> {
let key = process_fingerprint(cmd, extra_fingerprint);
if let std::collections::hash_map::Entry::Vacant(e) = self.data.outputs.entry(key) {
debug!("rustc info cache miss");
debug!("running {}", cmd);
let output = cmd.output()?;
let stdout = String::from_utf8(output.stdout)
.map_err(|e| anyhow::anyhow!("{}: {:?}", e, e.as_bytes()))
.with_context(|| format!("`{}` didn't return utf8 output", cmd))?;
let stderr = String::from_utf8(output.stderr)
.map_err(|e| anyhow::anyhow!("{}: {:?}", e, e.as_bytes()))
.with_context(|| format!("`{}` didn't return utf8 output", cmd))?;
e.insert(Output {
success: output.status.success(),
status: if output.status.success() {
String::new()
} else {
cargo_util::exit_status_to_string(output.status)
},
code: output.status.code(),
stdout,
stderr,
});
self.dirty = true;
} else {
debug!("rustc info cache hit");View on GitHub (pinned to 0e07a15537)
Solutions
- Set a UTF-8 locale: `export LC_ALL=C.UTF-8` (or `en_US.UTF-8`).
- Remove or fix any `RUSTC_WRAPPER` / `build.rustc-wrapper` that writes non-UTF-8 to stdout (wrappers must keep stdout clean for cargo).
- Reinstall/repair the toolchain with `rustup toolchain install`.
- Run the failing rustc command manually and inspect its raw stdout bytes.
Example fix
# before (wrapper pollutes stdout) export RUSTC_WRAPPER=./my-wrapper cargo build # after (wrapper silent on stdout, or unset) unset RUSTC_WRAPPER cargo build
Defensive patterns
Strategy: validation
Validate before calling
use std::process::Command;
fn rustc_stdout_is_utf8(rustc: &str) -> Result<(), String> {
let out = Command::new(rustc).arg("-vV").output().map_err(|e| e.to_string())?;
String::from_utf8(out.stdout).map(|_| ()).map_err(|e| format!("rustc stdout not UTF-8: {e}"))
} Type guard
fn rustc_emits_utf8_stdout(rustc: &str) -> bool {
std::process::Command::new(rustc).arg("-vV").output()
.map(|o| std::str::from_utf8(&o.stdout).is_ok()).unwrap_or(false)
} Try / catch
// Validate wrapper output before letting cargo cache it.
if let Err(e) = String::from_utf8(stdout_bytes.clone()) {
eprintln!("rustc/wrapper stdout is not UTF-8 ({e}); fix the wrapper or locale");
} Prevention
- Set `LC_ALL=C.UTF-8` in CI and shells.
- Keep `RUSTC_WRAPPER` stdout clean (it must only echo what rustc would).
- Repair the toolchain if `rustc -vV` itself emits non-UTF-8.
When it happens
Trigger: Cargo runs rustc to query info (e.g. `rustc -vV`, `--print`, dep-info) and the rustc process writes non-UTF-8 bytes to stdout — e.g. a locale/localized rustc, a corrupted toolchain, or a custom RUSTC wrapper that emits binary data.
Common situations: A locale/env (`LC_ALL`, `LANG`) causing rustc to emit non-UTF-8 localized text; a misconfigured `RUSTC_WRAPPER`/`build.rustc-wrapper` that pollutes stdout; a broken/corrupt rustc binary; a rustc from a non-standard distribution.
Related errors
- malformed output when learning about crate-type {} informati
- output of --print={request} missing when learning about targ
- probably rustup rustc, but without rustup's env vars
- `{}` resolved to non-UTF value (`{}`)
- rustc load ok
AI-assisted analysis of rust-lang/cargo@0e07a15537 (2026-08-06).
Data as JSON: /data/errors/858c4dd84b4b589b.json.
Report an issue: GitHub.