Safeguard
Developer Tools•

How do I force a patched transitive version in Gradle?

Use a Gradle constraint to raise a vulnerable transitive library to a patched version, add strictly only if needed, verify with dependencyInsight.

Safeguard Security Team
3 min read

Declare a dependency constraint for the vulnerable module at the patched version. A constraint sets a version requirement without adding the module to your graph, and it reaches transitive dependencies. Verify the result with the dependencyInsight task, and use strictly only when you must stop later upgrades.

Definition: constraint, exclude, force

A constraint says which version to use if the module shows up. It adds nothing by itself. An exclude removes a module from the graph. A force in a resolution strategy overrides selection, and Gradle notes that a consumer's force can override even a strictly declaration.

The Gradle documentation says constraints are not strict by default and usually mean at least this version. Gradle can still choose something higher.

The shortest fix

dependencies {
    constraints {
        implementation("com.fasterxml.jackson.core:jackson-databind:2.16.1") {
            because("patched, see advisory in ticket SEC-123")
        }
    }
}

The because text is the most useful line. It records why the pin exists, so a later cleanup does not remove it.

Constraints are transitive, so a library you publish carries them to its consumers. The docs prefer constraints over excludes for that reason.

When you need strictly

If another dependency asks for a higher version and you must stay on yours, for instance because a newer one breaks your code, use strictly. It pins an exact version or range so other dependencies cannot move it. At the same depth, strictly declarations are intersected, and an empty intersection fails resolution. Across depths, the one closest to the root wins.

Use it sparingly. A strict pin on a vulnerable library freezes the vulnerability too.

Excluding instead

Gradle can drop a module with exclude(group, module). One caveat from the docs: an exclusion applies only if all paths to the dependency agree on it. Constraints are usually the better tool for versions, and exclusion needs careful testing to avoid NoClassDefFoundError.

Steps

  1. Run the dependencyInsight task for the module, naming the runtimeClasspath configuration.
  2. Read the selection reasons, then add the constraint.
  3. Rerun the same command. The reason should now read by constraint.
  4. Refresh your lockfile if you use one, see Gradle dependency locking.
  5. Rescan.

Try it yourself

Click through it at your own pace, or open it full screen.

Find a finding with a fixed version and note which package would need the constraint.

Where Safeguard fits

Safeguard scans dependencies and SBOMs for Java builds and can propose fix pull requests when you enable autonomous remediation, which is off by default. There is a free scan to start from.

Quick check

Does a constraint add the library to my build?

No. It only influences the version if something else brings the library in.

How do I confirm the patched version is used?

Run dependencyInsight for the module and read the selection reasons. It will say by constraint when yours won.

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.