Present means the vulnerable library is on your classpath. Reachable means a call path from your application reaches the vulnerable function. Reachable findings come first, but a present, unreachable one is still worth fixing, because code changes and reflection can make it reachable later.
Definitions
Present. The component appears in your dependency tree or inventory at an affected version.
Reachable. Static analysis finds a path from your entry points to the vulnerable code. Some tools add runtime evidence.
Exploitable. Reachable, and an attacker can supply the input that triggers it in your deployment. That is the narrowest set.
| Level | Question | Typical effect on priority |
|---|---|---|
| Present | Is it on the classpath? | Track |
| Reachable | Can my code call it? | Fix soon |
| Exploitable | Can an attacker trigger it here? | Fix first |
Why Java makes this hard
Static call graphs struggle with features that Java frameworks rely on. Reflection, dependency injection, service loading and annotation-driven wiring create calls that are not visible in plain source. The Maven dependency plugin analyzes bytecode and ships options to correct false positives, which shows how often static analysis needs a human check. Libraries loaded by reflection or service lookup are the usual trouble, and the same weakness affects any static reachability method.
So a not reachable verdict in Java is evidence, not proof.
How to use reachability without fooling yourself
- Start with the full present list from your SBOM or tree.
- Use reachability to order the list, not to delete from it.
- For each not reachable finding, note why: library function never called, or optional feature disabled.
- Be careful with dependencies loaded by frameworks, like logging, serialization, web servers and database drivers. Treat those as reachable unless you can show otherwise.
- Re-evaluate when you add features or upgrade a framework.
- Keep the cheap fix. If a patched version is available and a bump is low risk, do it regardless.
An example of reasoning
Suppose an advisory affects a parsing function in a library. Your application pulls the library in transitively, never calls the parser, and does not enable the framework feature that would. That finding drops in priority. If another service passes untrusted input into that parser, it rises to the top. Same library, different answer per service.
Why this matters for backlogs
Large Java applications can carry hundreds of present findings. Reachability gives teams a credible order of work, so the urgent ones are fixed first and the rest follow in routine upgrades. See how to find vulnerable dependencies in your project.
Try it yourself
Click through it at your own pace, or open it full screen.
Compare the list before and after the reachable filter, and note which findings drop out.
Where Safeguard fits
Safeguard includes reachability analysis alongside SBOM and dependency scanning, so findings can be ordered by whether your code can reach them. The free scan is the quickest way to see a result.
Quick check
Can I ignore an unreachable vulnerability?
Deprioritise it, do not forget it. Keep it in the backlog and recheck when the code changes.
Is reachable the same as exploitable?
No. Exploitable also needs an attacker to be able to supply the triggering input in your deployment.
Sources
Last reviewed: 19 October 2026.