rust-lang/cargo · error

multiple packages link to native library

Error message

multiple packages link to native library `{}`, but a native library can be linked only once

{}
links to native library `{}`

{}
also links to native library `{}`

What it means

Two packages in the dependency graph both declare `links = "<lib>"` for the same native library name. Cargo enforces that each native library is linked by exactly one package (to avoid duplicate symbols / `-l` flags), and bails showing the two dependency paths to the conflicting packages.

Solutions

  1. Pick one source of the native linkage: remove or rename the `links` value on the duplicate, or exclude one version from the graph.
  2. If two unrelated crates legitimately wrap the same system lib, deduplicate by having one depend on the other.
  3. Use `cargo tree -i <pkg>` to find both paths and resolve the version conflict.
  4. Patch the offending crate to use a unique `links` name when vendoring.

Example fix

// before (Cargo.toml of crate A and crate B)
links = "sqlite3"

// after (crate B)
links = "sqlite3_b"
# or remove `links` from crate B and depend on crate A
Defensive patterns

Strategy: validation

Validate before calling

fn unique_links_values(manifests: &[&Manifest]) -> bool {
    let mut seen = std::collections::HashSet::new();
    manifests.iter().filter_map(|m| m.links()).all(|l| seen.insert(l))
}

Type guard

null

Try / catch

null

Prevention

When it happens

Trigger: Two crates in the resolved graph set identical `links = "foo"` in their manifests; a dependency was duplicated via different version requirements that both carry the same `links`.

Common situations: Vendoring a library that's also pulled transitively; forked crates that didn't change the `links` value; version conflicts where both 1.x and 2.x of a crate link the same native lib.

Related errors


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

Appendix: source

Thrown at src/compiler/links.rs:44

    units.sort_unstable();
    for unit in units {
        if !validated.insert(unit.pkg.package_id()) {
            continue;
        }
        let Some(lib) = unit.pkg.manifest().links() else {
            continue;
        };
        if let Some(&prev) = links.get(lib) {
            let prev_path = resolve
                .path_to_top(&prev)
                .into_iter()
                .map(|(p, d)| (p, d.and_then(|d| d.iter().next())));
            let pkg = unit.pkg.package_id();
            let path = resolve
                .path_to_top(&pkg)
                .into_iter()
                .map(|(p, d)| (p, d.and_then(|d| d.iter().next())));
            anyhow::bail!(
                "multiple packages link to native library `{}`, \
                 but a native library can be linked only once\n\
                 \n\
                 {}\nlinks to native library `{}`\n\
                 \n\
                 {}\nalso links to native library `{}`",
                lib,
                describe_path(prev_path),
                lib,
                describe_path(path),
                lib
            )
        }
        links.insert(lib.to_string(), unit.pkg.package_id());
    }
    Ok(())
}

View on GitHub (pinned to eb98b54bc9)