When Maven finds several versions of the same artifact in your dependency tree, it picks the one closest to your project, not the newest. If two are at the same depth, the first declaration wins. You can always force a version by declaring it explicitly in your own POM.
The rule
The Maven documentation calls this dependency mediation. It says Maven picks the nearest definition, meaning the version of the dependency closest to your project in the tree.
The documented example: A depends on B, B on C, C on D 2.0, and A also depends on E, E on D 1.0. Building A uses D 1.0, because the path through E is shorter.
The trap
Nearest is not the same as safest or newest. If a close dependency happens to ask for an old version of a library, your build uses that old version even though a deeper dependency asked for something newer.
That surprises people in two ways:
- A vulnerable version can win because a nearby package asked for it.
- A fix you expected from upgrading one library does not arrive, because another path is closer.
The tie break is also easy to overlook. At equal depth, declaration order in the POM decides.
How to take control
Declare the version yourself. The docs say you can guarantee a version by declaring it in your project's POM. A direct declaration is at depth one, so it wins.
Use dependencyManagement. This lets project authors specify the versions to use when an artifact appears transitively or when no version is given. The documentation notes that dependency management takes precedence over mediation for transitive dependencies. It does not affect the dependencies of plugins, only project dependencies.
Use exclusions. If project X depends on Y and Y depends on Z, X's owner can exclude Z explicitly.
<exclusions>
<exclusion>
<groupId>group-c</groupId>
<artifactId>excluded-artifact</artifactId>
</exclusion>
</exclusions>
Exclusions remove a branch entirely, so make sure nothing needs it at runtime.
A routine for a fix
- Print the dependency tree and find every path to the library.
- Note which version Maven chose and why it won.
- Prefer a managed version over scattering direct declarations.
- Rebuild and run tests, paying attention to code that uses the changed library.
- Record the reason next to the entry, so the next person knows when to remove it.
Link to scanning
A scanner that only looks at your direct declarations can miss the chosen transitive version. Look for tools that resolve the full tree. The demo below shows a dependency inventory.
Click through it at your own pace, or open it full screen.
Safeguard's SBOM and dependency scanning can be tried free at gold.safeguard.sh/scan. See also fixing vulnerabilities in Maven projects.
Quick check
Does Maven choose the highest version?
No. It chooses the nearest definition to your project. At equal depth, the first declaration wins.
What is the quickest way to force a version?
Declare it explicitly in your own POM, or manage it in dependencyManagement.
Sources
Last reviewed: 19 October 2026.