In Rust
Last updated: Aug 10, 2026
A transitive dependency (also called an indirect dependency) is a package that your project does not depend on directly, but that is required by one of your direct or intermediate dependencies.
The following strategies are listed in escalation order: try each one in sequence and move to the next only if the previous one does not resolve the issue.
Identify the dependency chain
Strategies 2 and 3 require knowing which direct or intermediate dependency pulls in the vulnerable crate:
cargo tree -i <crate>The -i flag inverts the tree,
putting the crate you named at the root
and branching out towards the crates that depend on it.
To find out whether the same crate is present at more than one version,
run:
cargo tree -dStrategy 1: Update the transitive dependency
The first and simplest approach is to update the vulnerable crate directly.
cargo update -p <crate>If you need an exact version rather than the newest acceptable one, name it:
cargo update -p <crate> --precise <safe-version>This works when the version requirements declared across the tree
allow for a release that includes the security patch.
If a direct or intermediate dependency requires a range
that excludes the patched release,
cargo update -p <crate> will not move it.
Strategy 2: Update the direct or intermediate dependency
If the transitive crate was not updated in the previous step,
the direct or intermediate dependency is likely constraining its version.
Update the version of the direct dependency in your Cargo.toml:
[dependencies]
direct-or-intermediate-crate = "<new-version>"This may pull in a newer version of the transitive crate that includes the security fix. Note that the direct dependency may already be at its latest version and still require the vulnerable crate, in which case this strategy will also be insufficient.
Strategy 3: Patch the dependency
Cargo has no version override.
The only way to replace a crate across the whole graph
is [patch], which redirects it to a different source
rather than to a different version of the registry:
You have to supply the fixed code yourself: fork the crate, apply the patch on your fork, and point the entry at it.
[patch.crates-io]
<crate> = { git = "https://github.com/<you>/<crate>", branch = "<branch>" }The patch is transitive and applies to the entire dependency graph, but it can only be declared in the manifest at the root of the workspace.
The patched source must remain SemVer compatible with what the graph requires,
and in Cargo compatibility is set by the leftmost non-zero component: 0.30
and 0.31 are incompatible with each other, the same way 1.0 and 2.0 are.
If you patch across that boundary, the patch is not applied and you end up
with two copies of the crate instead of one.
Strategy 4: Wait for maintainers, or drop the crate
If no patch is viable, the usual path is to wait for the upstream maintainers, which involves two separate releases:
- The maintainers of the vulnerable crate publish a patched version.
- The maintainers of the direct or intermediate dependency release a new version that adopts it.
Rust has a case with no equivalent in other ecosystems, though. A large share of RUSTSEC advisories report a crate as unmaintained, and those often have no patched version at any level of the tree. No strategy resolves them, because there is nothing to update to. Your options are to remove the dependency, frequently by turning off the default features that pull it in, or to accept the risk through your vulnerability management workflow.
In Kotlin
Learn the recommended strategies to remediate SCA vulnerabilities found in transitive Kotlin Gradle dependencies, from raising a version constraint to forcing a resolution strategy.
Introduction to Sorts
Learn about Sorts, the Fluid Attacks AI tool for prioritizing files in your software according to their likelihood of having vulnerabilities.