{"id":"26dde2830d29878f","repo":"rust-lang/cargo","slug":"multiple-packages-link-to-native-library-but","errorCode":null,"errorMessage":"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 `{}`","messagePattern":"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 `(.+?)`","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/compiler/links.rs","lineNumber":44,"sourceCode":"    units.sort_unstable();\n    for unit in units {\n        if !validated.insert(unit.pkg.package_id()) {\n            continue;\n        }\n        let Some(lib) = unit.pkg.manifest().links() else {\n            continue;\n        };\n        if let Some(&prev) = links.get(lib) {\n            let prev_path = resolve\n                .path_to_top(&prev)\n                .into_iter()\n                .map(|(p, d)| (p, d.and_then(|d| d.iter().next())));\n            let pkg = unit.pkg.package_id();\n            let path = resolve\n                .path_to_top(&pkg)\n                .into_iter()\n                .map(|(p, d)| (p, d.and_then(|d| d.iter().next())));\n            anyhow::bail!(\n                \"multiple packages link to native library `{}`, \\\n                 but a native library can be linked only once\\n\\\n                 \\n\\\n                 {}\\nlinks to native library `{}`\\n\\\n                 \\n\\\n                 {}\\nalso links to native library `{}`\",\n                lib,\n                describe_path(prev_path),\n                lib,\n                describe_path(path),\n                lib\n            )\n        }\n        links.insert(lib.to_string(), unit.pkg.package_id());\n    }\n    Ok(())\n}\n","sourceCodeStart":26,"sourceCodeEnd":62,"githubUrl":"https://github.com/rust-lang/cargo/blob/0e07a155371a6ce88ae53a2c00df940280c09a67/src/compiler/links.rs#L26-L62","documentation":"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.","triggerScenarios":"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).","commonSituations":"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.","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)."],"exampleFix":"# before - two crates link `zlib`\n# Cargo.toml of crate A: links = \"zlib\"\n# Cargo.toml of crate B: links = \"zlib\"\n# after - patch to a single source of zlib binding\n[patch.crates-io]\nflate2 = { git = 'https://...single-zlib-binding' }","handlingStrategy":"validation","validationCode":"# In CI, assert no duplicate links before building:\ncargo tree -e normal --prefix none | grep -i 'links' || true\n# Or a pre-build check script that scans Cargo.toml files:\n# rg '^links\\s*=' --type toml","typeGuard":null,"tryCatchPattern":null,"preventionTips":["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."],"tags":["links","native-library","dependency-graph","manifest"],"analyzedSha":"0e07a155371a6ce88ae53a2c00df940280c09a67","analyzedAt":"2026-08-06T01:46:58.334Z","schemaVersion":2}