rust-lang/cargo · error

found duplicate name , but all targets must have a unique…

Error message

found duplicate {target_kind} name {name}, but all {target_kind} targets must have a unique name

What it means

Within a single target kind (all `[[bin]]`, all `[[bench]]`, all `[[test]]`, or all `[[example]]` tables), each declared target must have a unique name. `validate_unique_names` walks the list, inserting names into a `HashSet`, and bails on the first collision. Duplicate names would produce ambiguous build artifacts.

Solutions

  1. Rename one of the colliding targets so each `name` is unique within its kind.
  2. If the duplicate is unintended, delete the extra table.
  3. Run `cargo metadata` to confirm target names are now distinct.

Example fix

# before
[[bin]]
name = "server"
path = "src/bin/server_a.rs"

[[bin]]
name = "server"
path = "src/bin/server_b.rs"

# after
[[bin]]
name = "server_a"
path = "src/bin/server_a.rs"

[[bin]]
name = "server_b"
path = "src/bin/server_b.rs"
Defensive patterns

Strategy: validation

Validate before calling

use std::collections::HashSet;
fn unique_target_names(targets: &[(String, String)]) -> bool {
    // targets: Vec<(kind, name)>
    let mut seen = HashSet::new();
    targets.iter().all(|(kind, name)| seen.insert((kind.clone(), name.clone())))
}

Prevention

When it happens

Trigger: Two (or more) tables of the same kind declare an identical `name`. E.g. two `[[bin]]` entries both with `name = "server"`. The `!seen.insert(name)` check at targets.rs:899 fails.

Common situations: Copy-pasting a `[[bin]]` block and forgetting to rename. Merging manifests during a refactor. Automated generation that appends targets without dedup.

Related errors


AI-assisted analysis of rust-lang/cargo@eb98b54bc9 (2026-08-11). Data as JSON: /api/errors/e6275e85b54a57f6. Report an issue: GitHub.

Appendix: source

Thrown at src/workspace/parser/targets.rs:894

}

fn inferred_to_toml_targets(inferred: &[(String, PathBuf)]) -> Vec<TomlTarget> {
    inferred
        .iter()
        .map(|(name, path)| TomlTarget {
            name: Some(name.clone()),
            path: Some(PathValue(path.clone())),
            ..TomlTarget::new()
        })
        .collect()
}

/// Will check a list of toml targets, and make sure the target names are unique within a vector.
fn validate_unique_names(targets: &[TomlTarget], target_kind: &str) -> CargoResult<()> {
    let mut seen = HashSet::default();
    for name in targets.iter().map(|e| name_or_panic(e)) {
        if !seen.insert(name) {
            anyhow::bail!(
                "found duplicate {target_kind} name {name}, \
                 but all {target_kind} targets must have a unique name",
                target_kind = target_kind,
                name = name
            );
        }
    }
    Ok(())
}

/// Will check a list of build scripts, and make sure script file stems are unique within a vector.
fn validate_unique_build_scripts(scripts: &[String]) -> CargoResult<()> {
    let mut seen = HashMap::default();
    for script in scripts {
        let stem = Path::new(script)
            .file_stem()
            .and_then(|s| s.to_str())
            .expect("previously normalized");

View on GitHub (pinned to eb98b54bc9)