In Kotlin
Last updated: Sep 30, 2026
A transitive dependency (also called an indirect dependency) is a package that your project does not use directly. One of your direct or intermediate dependencies needs it.
Try the strategies below in this sequence. Move to the next strategy only if the previous one does not correct the problem.
Identify the dependency chain
For strategies 2 and 3, find the direct or intermediate dependency that pulls in the vulnerable package. Use Gradle:
./gradlew dependencyInsight --dependency <package> --configuration runtimeClasspathIn a multi-module build,
prefix the task with the module, as in :app:dependencyInsight.
Use the configuration of that module
(releaseRuntimeClasspath or debugRuntimeClasspath on Android).
Strategy 1: Update the transitive dependency
The first and simplest method is to increase the minimum permitted version of the vulnerable dependency with a constraint. Gradle corrects version conflicts with the highest requested version. A constraint increases the floor, and the resolver keeps the decision.
Add this to your build.gradle.kts:
dependencies {
constraints {
implementation("group:<package>:<safe-version>") {
because("<advisory id>")
}
}
}This works when nothing in the dependency tree pins the package to one vulnerable version. A dependency with a strict version conflicts with the constraint. Gradle then fails the resolution and does not do the upgrade. Thus, this strategy does not correct the problem.
Strategy 2: Update the direct or intermediate dependency
If strategy 1 did not update the transitive dependency,
a direct or intermediate dependency probably constrains its version.
Update the version of the direct dependency in your build.gradle.kts:
implementation("group:direct-or-intermediate-artifact:new-version")This can pull in a newer version of the transitive dependency with the security fix. But the direct dependency can be at its latest version and continue to use the vulnerable transitive package. If it does, this strategy also does not correct the problem.
Strategy 3: Use dependency overrides
When the constraint of strategy 1 does not correct the problem,
force a safe version.
Unlike a constraint,
force bypasses the conflict resolution fully.
Gradle stops the negotiation and imposes the version that you name.
Add a resolution strategy to your build.gradle.kts:
configurations.all {
resolutionStrategy {
force("group:<package>:<safe-version>")
}
}Overrides bypass the version resolution logic of the package manager. They can cause incompatibilities. Before you merge, run all tests and linters locally. Make sure that the CI pipeline passes. If something breaks, move to strategy 4.
Strategy 4: Wait for maintainers
If the override introduces breaking changes, the safest path is to wait for the upstream maintainers to fix the vulnerability. Two releases are necessary:
- The maintainers of the vulnerable package publish a patched version.
- The maintainers of the direct or intermediate dependency release a new version that adopts the patched transitive dependency.
This procedure can continue for days or longer. In the meantime, you can accept the risk through your vulnerability management workflow. Monitor the upstream project. Update when a safe version is available.
In Python
Learn the recommended strategies to remediate SCA vulnerabilities found in transitive Python dependencies, from updating packages to using uv dependency overrides.
In Rust
Learn the recommended strategies to remediate SCA vulnerabilities found in transitive Rust dependencies, from updating crates to patching a fork.