rust-lang/cargo · error · anyhow::Error
the replacement specification `{}` matched multiple packages
Error message
the replacement specification `{}` matched multiple packages:
* {}
{} What it means
Raised in `dep_cache.rs` while processing `[replace]` (the legacy `[replace]` table) override specs. A single replacement spec resolved to two or more distinct candidate packages in the registry (same name requirement, multiple matching versions returned by `query_vec`). Cargo requires a `[replace]` spec to match exactly one package version so the substitution is unambiguous; more than one means it cannot decide which to substitute.
Source
Thrown at src/resolver/dep_cache.rs:143
_ => None,
});
let s = summaries.next().ok_or_else(|| {
anyhow::format_err!(
"no matching package for override `{}` found\n\
location searched: {}\n\
version required: {}",
spec,
dep.source_id(),
dep.version_req()
)
})?;
let summaries = summaries.collect::<Vec<_>>();
if !summaries.is_empty() {
let bullets = summaries
.iter()
.map(|s| format!(" * {}", s.package_id()))
.collect::<Vec<_>>();
return Err(anyhow::anyhow!(
"the replacement specification `{}` matched \
multiple packages:\n * {}\n{}",
spec,
s.package_id(),
bullets.join("\n")
));
}
assert_eq!(
s.name(),
summary.name(),
"dependency should be hard coded to have the same name"
);
if s.version() != summary.version() {
return Err(anyhow::anyhow!(
"replacement specification `{}` matched {} and tried to override it with {}\n\
avoid matching unrelated packages by being more specific",
spec,View on GitHub (pinned to 0e07a15537)
Solutions
- Pin the replacement dependency to an exact version in the `[replace]` entry so only one package matches.
- Switch from `[replace]` to the supported `[patch]` table, which handles multi-version matching differently.
- Make the replace spec's version requirement more specific (e.g. `=1.0.184` instead of `^1.0`).
Example fix
# before
[replace]
"serde:1.0.0" = { path = "../my-serde" }
# after
[patch.crates-io]
serde = { path = "../my-serde" } Defensive patterns
Strategy: validation
Validate before calling
# In CI, lint Cargo.toml to forbid [replace] (use [patch] instead): if grep -nq '^\[replace\]' Cargo.toml; then echo 'ERROR: [replace] is deprecated and error-prone; use [patch]'; exit 1; fi
Prevention
- Prefer `[patch]` over the deprecated `[replace]` table.
- Pin replacement dependency versions exactly (`=x.y.z`) so only one package matches.
- Run `cargo check` after editing replacement specs to catch multi-match errors early.
When it happens
Trigger: Using `[replace]` in `Cargo.toml` with a version requirement broad enough to match multiple published versions of the override target, e.g. `[replace] "serde:1.0.0" = { path = "../my-serde" }` where the registry query returns several 1.0.x versions that all satisfy the replacement dependency's version req. The first candidate plus remaining `summaries` being non-empty triggers the bail.
Common situations: Migrating from `[replace]` to `[patch]` incorrectly; broad version wildcards (`*`, `^1`) on replacement dependency specs; replacement target crates that publish many versions fitting the req. `[replace]` is deprecated, so this surfaces mostly in older configs.
Related errors
- overlapping replacement specifications found: * {} * {}
- replacement specification `{}` matched {} and tried to overr
- subcommand is required, add a subcommand to the command alia
- alias {} has unresolvable recursive definition: {} -> {}
- subcommand is required, but `{alias_name}` is empty
AI-assisted analysis of rust-lang/cargo@0e07a15537 (2026-08-06).
Data as JSON: /data/errors/5cb513c5da637e0c.json.
Report an issue: GitHub.