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

  1. Pin the replacement dependency to an exact version in the `[replace]` entry so only one package matches.
  2. Switch from `[replace]` to the supported `[patch]` table, which handles multi-version matching differently.
  3. 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

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


AI-assisted analysis of rust-lang/cargo@0e07a15537 (2026-08-06). Data as JSON: /data/errors/5cb513c5da637e0c.json. Report an issue: GitHub.