rust-lang/cargo · error
several matching instances of `target.'cfg(..)'.linker` in c
Error message
several matching instances of `target.'cfg(..)'.linker` in configurations
first match `{}` located in {}
second match `{}` located in {} What it means
In target_linker (compilation.rs:581-600), Cargo selects a `target.'cfg(...)'.linker` by filtering all configured cfg-linker entries whose cfg key matches the current target. If more than one matches, the linker choice is ambiguous and Cargo bails, printing the first and second matching keys and the config-file locations (definition) that defined each.
Source
Thrown at src/compiler/compilation.rs:591
// With `target-applies-to-host = true`,
// host artifacts must fall through to pick up from [target]
// since this is the stable behavior
if kind.is_host() && !bcx.gctx.target_applies_to_host()? {
return Ok(None);
}
// Try target.'cfg(...)'.linker.
let target_cfg = bcx.target_data.info(kind).cfg();
let mut cfgs = bcx
.gctx
.target_cfgs()?
.iter()
.filter_map(|(key, cfg)| cfg.linker.as_ref().map(|linker| (key, linker)))
.filter(|(key, _linker)| CfgExpr::matches_key(key, target_cfg));
let matching_linker = cfgs.next();
if let Some((key, linker)) = cfgs.next() {
anyhow::bail!(
"several matching instances of `target.'cfg(..)'.linker` in configurations\n\
first match `{}` located in {}\n\
second match `{}` located in {}",
matching_linker.unwrap().0,
matching_linker.unwrap().1.definition,
key,
linker.definition
);
}
Ok(matching_linker.map(|(_k, linker)| linker.val.clone().resolve_program(bcx.gctx)))
}
fn explicit_host_kind(host: &str) -> CompileKind {
let target = CompileTarget::new(host, false).expect("must be a host tuple");
CompileKind::Target(target)
}
View on GitHub (pinned to 0e07a15537)
Solutions
- Keep only ONE matching cfg-linker entry; remove or narrow the broader expression.
- Prefer an exact-triple key (`[target.<triple>.linker]`) over overlapping cfgs.
- Run `cargo config get` / inspect layered config files for duplicate linker definitions.
- Make cfg conditions mutually exclusive so they cannot both match the same target.
Example fix
// before (.cargo/config.toml) [target.'cfg(unix)'.linker] linker = "clang" [target.'cfg(linux)'.linker] linker = "gcc" // both match linux -> error // after [target.'cfg(target_os = "macos")'.linker] linker = "clang" [target.'cfg(target_os = "linux")'.linker] linker = "gcc"
Defensive patterns
Strategy: validation
Validate before calling
let matching: Vec<_> = target_cfgs.iter()
.filter(|(_, c)| c.linker.is_some())
.filter(|(k, _)| CfgExpr::matches_key(k, &target_cfg))
.collect();
if matching.len() > 1 {
return Err(format!("{} target.'cfg(..)'.linker match; disambiguate", matching.len()));
} Type guard
fn single_linker_match(entries: &[(&str, &Config)]) -> bool {
entries.iter().filter(|(_, c)| c.linker.is_some()).count() <= 1
}
Prevention
- Audit layered cargo config for linker duplicates.
- Use exact-triple linker keys to avoid cfg overlap.
- Run `cargo config get` to inspect merged config in CI.
When it happens
Trigger: Defining multiple `[target.'cfg(...)'.linker]` entries (across `.cargo/config.toml`, `~/.cargo/config.toml`, or `--config`) whose cfg expressions both evaluate true for the build target — e.g. `[target.'cfg(unix)'.linker]` and `[target.'cfg(target_arch = "x86_64")'.linker]` both matching an x86_64 linux build.
Common situations: Overlapping linker config from global + project files; cross-compilation setups that add a broad cfg-linker that collides with an existing one; merging team config; combining an exact-triple linker with a cfg-based one that also matches.
Related errors
- several matching instances of `target.'cfg(..)'.runner` in c
- subcommand is required, add a subcommand to the command alia
- alias {} has unresolvable recursive definition: {} -> {}
- subcommand is required, but `{alias_name}` is empty
- dependency `{}` in package `{}` requires a `{}` artifact to
AI-assisted analysis of rust-lang/cargo@0e07a15537 (2026-08-06).
Data as JSON: /data/errors/b0da7054d6d14665.json.
Report an issue: GitHub.