Safeguard
Supply Chain•

How do I ban crates and duplicate versions with cargo deny?

The cargo deny bans check blocks named crates, flags duplicate versions and wildcard requirements. Keys, defaults, skip options and a rollout plan.

Safeguard Security Team
3 min read

Use the [bans] table in deny.toml: list unwanted crates under deny, set multiple-versions to flag duplicates, and set wildcards to catch star version requirements. Defaults for the last two are warn. Use skip for known duplicates, with a reason on each.

The keys

KeyPurposeDefault
multiple-versionsWhat to do when two versions of one crate are in the graphwarn
wildcardsWhat to do for dependencies using a star versionwarn
denyCrates you never want, with optional reason and replacementnone
skipIgnore a crate during duplicate detectionnone
skip-treeSkip a crate and everything below itdepth unlimited

The documentation calls skip-tree a very big hammer, and it is. Prefer skip entries one crate at a time.

Why duplicates matter for security

Two versions of the same crate means two copies of its code in your binary, and a fix in one may leave the other exposed. When an advisory lands, you have to patch both, and the older copy is often held there by one stubborn parent crate. Duplicates also add build time and binary size, as the Cargo documentation notes for its duplicates view.

Finding the cause before banning

Run cargo tree -d to list crates that appear in more than one version. Then use the inverted view, for example cargo tree -i crate_name, to see which parent pulls in each copy. Often one update of one parent removes the duplicate.

Banning a crate

[bans]
multiple-versions = "warn"
wildcards = "deny"
deny = [
    { crate = "openssl", reason = "we standardise on one TLS stack", use-instead = "rustls" },
]

The names here are examples of the config shape, not a recommendation about any crate. Pick bans from your own policy, such as a TLS stack decision or a crate your legal team rejected.

Wildcards

A bare star requirement lets any version satisfy the dependency. crates.io does not allow bare star versions on published crates, according to the Cargo reference, but they can appear in path or git dependencies inside a workspace. Denying wildcards keeps version intent explicit.

Rollout steps

  1. Run the check with warn and capture the baseline.
  2. Fix the cheap duplicates with a conservative update.
  3. Add skip entries, each with a reason, for the rest.
  4. Add real bans from policy.
  5. Move wildcards to deny, and consider multiple versions at deny once the list is short.

Quick check

Should multiple-versions be deny from day one?

Usually no. Large graphs have legitimate duplicates, so start at warn and shrink the list.

What is the difference between skip and skip-tree?

Skip ignores one crate in duplicate detection. Skip-tree also ignores its transitive dependencies, so it hides much more.

Safeguard SBOM and dependency scanning shows the full set of versions in your graph, and a free scan is available at gold.safeguard.sh/scan.

Sources

Last reviewed: 19 October 2026.

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.

Self-healing security runs on Safeguard.

Your first fix PR is minutes away.

No sales call required, even your agent can complete the purchase over MCP.