Safeguard
Developer Tools•

Why does Gradle pick a newer SDK version than the one I declared?

Gradle resolves version conflicts by choosing the highest requested version. Here is how that changes an Android SDK without a diff in your build file.

Safeguard Security Team
4 min read

Because Gradle resolves a version conflict by selecting the highest version that any part of your dependency graph asks for. If another library needs a newer release of an SDK than the one you declared, you get the newer one, even though your build file never changed.

What is a version conflict?

A version conflict happens when two components depend on the same module at different versions. Your app might declare analytics SDK 4.1, while a payment library you also use depends on analytics SDK 4.3. Gradle builds one resolved graph, so only one version can ship in the app.

According to the Gradle documentation, the default behaviour is to pick the highest version. The details depend on how versions are declared. Without ranges, the highest non-rejected version wins. With a strictly declaration that is lower than the highest requested version, resolution fails rather than quietly downgrading.

Why this matters for upgrade and deprecation risk

Two things follow for mobile teams.

First, an SDK can upgrade without anyone touching it. A routine bump of a neighbouring library can pull your SDK to a version with new behaviour, a removed method or a changed permission. The release notes you read were for the version you thought you had.

Second, the reverse is also true. You may believe you fixed a vulnerable SDK by bumping it, yet another dependency with a strict constraint holds an older copy in place, or resolution fails and nobody notices until the build breaks.

How to see what you actually ship

  1. Run the dependency report for your release configuration, for example the runtime classpath of the release variant, and search it for the SDK name.
  2. Look for lines showing one version arrowed to another. That marks a conflict where Gradle overrode a requested version.
  3. Note who asked for the higher version. The path to the dependency tells you which library pulled it.
  4. Record the resolved version in the release notes, not the declared one.

The same report is the right place to check variants. A debug build can resolve differently from release if dependencies are declared per configuration.

Ways to control it

ApproachWhat it doesTrade off
Do nothingHighest version winsSurprise upgrades from neighbours
Declare the version you want and keep it highestYour choice wins only if it is the highestDoes not stop a later neighbour from going higher
Use a strict constraintFails if a higher version is requestedForces a decision, can block builds
Use a dependency lockFreezes resolved versions between runsYou must refresh it on purpose
Use a platform or bill of materialsMoves related modules togetherNeeds the vendor to publish one

Locking is covered in our post on locking Android SDK versions with Gradle lockfiles. A lock records what resolved. A strict constraint states what you will accept. They solve different halves of the problem.

Try it yourself

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

Look for the difference between a direct dependency and one that arrives through another library. The second kind is where silent upgrades come from.

Where Safeguard fits

Dependency scanning and SBOM generation in Safeguard list the resolved versions in a build, including transitive ones, so you can compare them against what you declared. You can try a free scan at gold.safeguard.sh/scan.

Quick check

Does a higher version always win?

By default, yes, for versions without ranges. A strictly declared version that is lower than the highest requested one makes resolution fail instead.

Can my SDK change when I did not edit my build file?

Yes. If a different dependency requests a newer version of the same SDK, Gradle selects it. Check the resolved graph, not the declaration.

Does a lockfile stop this?

A lock keeps the resolved set stable between builds. It does not decide which version is right, so review the lock diff whenever it changes.

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.