rust-lang/cargo · error
multiple packages link to native library `{}`, but a native
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
Cargo enforces that the `package.links` manifest key is unique across the resolved dependency graph: each native library name may be linked by at most one crate. validate_links (links.rs:21-60) walks the unit graph; when a second package declares the same `links` value, it bails with a message listing both packages and their dependency paths to the top-level crate. The constraint exists because two crates linking the same native library would cause duplicate-symbol / double-link errors at link time.
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 0e07a15537)
Solutions
- Run `cargo tree` and locate the two crates sharing the `links` name; pick one and exclude/replace the other.
- Use `[patch]` or `[replace]` to collapse both onto a single version of the native-binding crate.
- If you own one of the crates, remove its `links` key if it does not actually need to claim the native library.
- Upgrade/downgrade one crate to a version that does not collide (check the crate's changelog for `links` changes).
Example fix
# before - two crates link `zlib`
# Cargo.toml of crate A: links = "zlib"
# Cargo.toml of crate B: links = "zlib"
# after - patch to a single source of zlib binding
[patch.crates-io]
flate2 = { git = 'https://...single-zlib-binding' } Defensive patterns
Strategy: validation
Validate before calling
# In CI, assert no duplicate links before building: cargo tree -e normal --prefix none | grep -i 'links' || true # Or a pre-build check script that scans Cargo.toml files: # rg '^links\s*=' --type toml
Prevention
- Run `cargo tree` to review the dependency graph for native-binding crates before adding new deps.
- Avoid adding two crates that bind the same C library; pick one binding and patch others onto it.
- When publishing a crate that binds a native lib, set `links` once and document it.
When it happens
Trigger: Two dependencies in the resolved graph both set `links = "foo"` in their Cargo.toml. Occurs during dependency resolution / build unit graph validation, before compilation. Common when two crates bind the same C library (e.g. two openssl bindings, two zlib bindings).
Common situations: Pulling in both `openssl-sys` and another crate that also links openssl; duplicate vendored copies of a native lib through different dependency versions; an older crate still carrying a `links` key that collides with a newer one.
Related errors
- dependency `{}` in package `{}` requires a `{}` artifact to
- Deprecated dependency sections are unsupported: {}
- the manifest file {} needs to be updated but {locked_flag} w
- package `{}` cannot be tested because it requires dev-depend
- could not compile due to {error_count} previous target resol
AI-assisted analysis of rust-lang/cargo@0e07a15537 (2026-08-06).
Data as JSON: /data/errors/26dde2830d29878f.json.
Report an issue: GitHub.