Write the reason a stranger would need: the advisory or bug, the version that fixes it, who owns the decision, and when to review it. Gradle's because clause attaches a human readable reason to a constraint, and it is the cheapest defense against pins nobody dares remove.
What a constraint does
The Gradle documentation says a dependency constraint sets a version requirement for a module without adding it as a dependency. Constraints are not strict by default. They usually mean at least this version, and they take part in conflict resolution like a declared version.
If nothing brings the module into the graph, the constraint has no effect. That makes constraints a good fit for transitive fixes: you say what version is acceptable, and Gradle applies it wherever the module shows up.
The documentation's example constrains a transitive codec library to a newer version and gives the reason as a known vulnerability in the version the HTTP client pulls in.
Why the reason matters across teams
Constraints live in a build file that several teams may touch. In a multi project build, the documentation recommends declaring constraints centrally in a java-platform project. That is a shared file, and shared files collect unexplained lines.
Six months later someone sees a constraint on a library and asks three questions. Is this still needed? Who added it? Will removing it break anything? A good reason answers all three. A missing one forces a guess, and the safe guess is to leave it forever.
A template that works
Keep it to one sentence plus identifiers.
- What it fixes. Advisory identifier or bug link.
- Which version is the floor. The fixed release.
- Why it is needed. Which dependency pulls in the old version.
- Owner. A person or team name.
- Review date. When to retry removal.
For example, a reason might read: advisory identifier, fixed in the stated version, pulled in by the HTTP client, owned by the payments team, review in January.
Reasons that do not help
| Weak reason | Why it fails | Better |
|---|---|---|
| security | Says nothing about what | Advisory identifier and fixed version |
| needed | Needed by whom? | Name the dependency that pulls it in |
| per John | John may leave | Team name and ticket link |
| temporary | No end date | Review date |
Handle disputes over constraints
If one team wants a constraint removed and another wants it kept, the reason decides it. Check whether the upstream dependency now asks for a fixed version. If it does, the constraint is redundant and can go. If it does not, the constraint stays, and the dispute becomes a request upstream.
Remember the documentation's note that constraints are published only with Gradle Module Metadata, so consumers using Maven or Ivy may not receive them. A constraint in your library may not protect users of other tools. Say so in the reason if it matters.
Quick check
Is a Gradle constraint the same as a dependency?
No. The documentation says it sets a version requirement without adding the module. It has no effect unless something else brings that module in.
Do constraints in my library reach every consumer?
Not always. The documentation says constraints are published only with Gradle Module Metadata, so Maven or Ivy consumers may not get them.
Sources
Last reviewed: 19 October 2026.