{"id":"d6979f7e791fc558","repo":"rust-lang/cargo","slug":"must-be-a-host-tuple","errorCode":null,"errorMessage":"must be a host tuple","messagePattern":"must be a host tuple","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/compiler/compilation.rs","lineNumber":605,"sourceCode":"        .filter_map(|(key, cfg)| cfg.linker.as_ref().map(|linker| (key, linker)))\n        .filter(|(key, _linker)| CfgExpr::matches_key(key, target_cfg));\n    let matching_linker = cfgs.next();\n    if let Some((key, linker)) = cfgs.next() {\n        anyhow::bail!(\n            \"several matching instances of `target.'cfg(..)'.linker` in configurations\\n\\\n             first match `{}` located in {}\\n\\\n             second match `{}` located in {}\",\n            matching_linker.unwrap().0,\n            matching_linker.unwrap().1.definition,\n            key,\n            linker.definition\n        );\n    }\n    Ok(matching_linker.map(|(_k, linker)| linker.val.clone().resolve_program(bcx.gctx)))\n}\n\nfn explicit_host_kind(host: &str) -> CompileKind {\n    let target = CompileTarget::new(host, false).expect(\"must be a host tuple\");\n    CompileKind::Target(target)\n}\n","sourceCodeStart":587,"sourceCodeEnd":608,"githubUrl":"https://github.com/rust-lang/cargo/blob/0e07a155371a6ce88ae53a2c00df940280c09a67/src/compiler/compilation.rs#L587-L608","documentation":"`explicit_host_kind` builds a `CompileTarget` from the host triple string via `CompileTarget::new(host, false).expect(\"must be a host tuple\")`. The `host` value comes from `bcx.host_triple()`, which Cargo obtained from `rustc -vV` and already validated as a real target tuple during target-data init. Re-parsing it must therefore succeed. Failure indicates the cached host triple is no longer parseable — typically a toolchain/sysroot change mid-build.","triggerScenarios":"`target-applies-to-host = false` combined with a host triple that the current rustc can no longer parse (e.g. rustc was swapped to one lacking that target); the rustc host tuple changed between `BuildContext` construction and the call to `target_runner`/`host_linker`.","commonSituations":"Concurrent `rustup` toolchain switch during a build; `RUSTUP_TOOLCHAIN` rewritten between Cargo sub-processes; `host` value stale across a Cargo-as-library long-lived `BuildContext`.","solutions":["Pin the toolchain with `rust-toolchain.toml` and restart the build.","Avoid changing `RUSTUP_TOOLCHAIN`/`RUSTC` while Cargo runs.","Run `cargo clean` after a toolchain change."],"exampleFix":"// before\nlet target = CompileTarget::new(host, false).expect(\"must be a host tuple\");\n// after\nlet target = CompileTarget::new(host, false).with_context(|| format!(\"host triple `{host}` is no longer parseable; did the toolchain change?\"))?;","handlingStrategy":"validation","validationCode":"// Confirm the host triple is parseable by the active rustc before relying on target-applies-to-host=false\nuse std::process::Command;\nfn host_triple_valid(host: &str) -> bool {\n    Command::new(\"rustc\").args([\"--print\", \"target-list\"]).output()\n        .map(|o| String::from_utf8_lossy(&o.stdout).lines().any(|l| l == host)).unwrap_or(false)\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Pin the toolchain with `rust-toolchain.toml`.","Don't change `RUSTUP_TOOLCHAIN`/`RUSTC` mid-build.","Run `cargo clean` after a toolchain switch."],"tags":["cargo","host-triple","toolchain","target-applies-to-host","internal-invariant"],"analyzedSha":"0e07a155371a6ce88ae53a2c00df940280c09a67","analyzedAt":"2026-08-06T01:46:58.334Z","schemaVersion":2}