Safeguard
Developer Tools•

How do Gradle dependency constraints and the because clause work?

Gradle constraints raise a transitive version without adding a direct dependency, and because documents why. A short how to for patching and later audits.

Safeguard Security Team
3 min read

A Gradle dependency constraint sets a version rule for a module without adding it to your build. If something pulls that module in, the constraint applies. If nothing does, it does nothing. Add a because message so the next person knows which vulnerability the constraint addresses.

Definition

Per the Gradle documentation, a constraint is not a dependency. A version on a dependency affects the dependencies you declare, no others. A constraint lets you control transitive dependencies you never declared. Constraints are not strict by default, so they usually mean "at least this version", and Gradle can still select a higher one.

The standard example

The Gradle docs use this case. A client library pulls in a codec library at a version with known vulnerabilities. You add a constraint for a fixed version, without making the codec a direct dependency, and Gradle upgrades the transitive version. Here is the shape:

dependencies {
    constraints {
        implementation("commons-codec:commons-codec:1.15") {
            because("httpclient pulls in 1.11 which has known vulnerabilities")
        }
    }
}

Why it beats a direct dependency

ApproachDownside
Declare the library directlyYour app now claims it as its own and it stays after the parent stops needing it
ConstraintApplies while something uses the module, so it cleans itself up

Steps

  1. Identify the vulnerable transitive version and the fixed one.
  2. Add a constraint for the fixed version.
  3. Write a because that names the advisory or reason.
  4. Run dependencies or dependencyInsight and confirm the new version resolves.
  5. Add a note with a review date so the constraint does not live forever unexplained.
  6. For tighter control use rich versions such as strictly, prefer or reject.

For several Gradle projects, forcing a patched transitive version with constraints goes deeper.

Caveat for libraries

Constraints are published through Gradle Module Metadata, so they may not survive consumption through Maven or Ivy. If you publish a library, do not assume your consumers inherit the constraint.

Try it yourself

Click through it at your own pace, or open it full screen. Follow a vulnerable package to the version that fixes it, which is the number your constraint should name.

Safeguard builds an SBOM and scans your dependencies for known vulnerabilities, and you can run a free scan at gold.safeguard.sh/scan to see what your own project pulls in.

Quick check

Does a constraint add the library to my app?

No. It applies if some other dependency already brings that module in.

Is a constraint strict?

Not by default. Gradle can still pick a higher version, which is usually what you want for a security fix.

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.