Why are some of my findings marked as Reachable, Unreachable, or Potentially Reachable?
Last updated: June 15, 2026
Context
When reviewing findings in Endor Labs, you may notice reachability tags such as Unreachable Dependency, Potentially Reachable Dependency, Potentially Reachable Function, etc. This article explains what those states mean, how Endor Labs determines which label applies, and how reachability tags interact with action policies.
Answer
Every SCA finding in Endor Labs is evaluated at two levels:
Dependency reachability: whether the affected package is sued anywhere in your application
Function reachability: whether a specific vulnerable function inside that package is callable from your code
Each level gets one of three reachability states. These tags describe what call graph analysis was able to prove about your project, not simply whether a dependency exists in your manifest file.
Function reachability is more precise and is evaluated only after dependency reachability. If Endor cannot confirm the dependency is reachable, it cannot confirm whether the function inside is reachable.
Dependency Reachability
The three finding states
Finding tag | What it means |
|---|---|
Reachable Dependency | Endor found at least one static call path from your code into the affected dependency |
Unreachable Dependency | No call path to the dependency was found, and call graph coverage of your project is complete. The absence of a path is treated as proof that the dependency is not in use. |
Potentially Reachable Dependency | The dependency is in your project, but Endor cannot definitively say reachable or unreachable because call graph coverage is incomplete. |
Common causes of an "Unreachable Dependency" finding
The dependency is declared but never used in source code. It exists in your manifest or lockfile, but no file in your project imports it.
The dependency is in the resolved dependency graph but no call path reaches it. Call graph analysis was complete for that part of the tree, and no entry point in your application calls into this dependency.
Common causes of a "Potentially Reachable Dependency" finding
A finding will be tagged Potentially Reachable Dependency when Endor cannot prove the dependency is reachable or unreachable. The most common causes are:
A call graph is missing somewhere on the path from your code to the affected dependency, either at the affected dependency itself or at an intermediate package along the way. This typically happens when:
The package's language or package manager is not supported for call graph analysis.
The scan ran in a mode that does not generate call graphs (for example, a quick scan).
Endor could not fetch the package artifact (private registry without credentials, yanked package, network failures).
Call graph generation failed for that package (malformed artifact, obfuscation, unsupported build tooling).
The dependency was identified through code-segment matching rather than manifest resolution.
When any of these happen, "no path found" cannot be trusted as proof, so Endor tags the finding as Potentially Reachable rather than Unreachable.
Your project was approximated. When Endor couldn't fully resolve your dependency graph (for example, because there is no committed lockfile), there is usually not enough call graph evidence to make a definitive claim. See approximate scans.
A note about test-scoped dependencies
Findings on test-scoped dependencies typically do not receive any of the three reachability tags. If you filter your findings by dependency reachability and don't see test-scoped findings included, that is expected behavior.
How dependency reachability relates to action policies
The action policy filter "Is the affected dependency reachable in the dependency tree?" is built directly on top of these three finding tags:
"Reachable Dependency" → matches findings tagged Reachable Dependency.
"Unreachable Dependency" → matches findings tagged Unreachable Dependency.
"Potentially Reachable Dependency" → matches findings tagged Potentially Reachable Dependency.
In other words, the policy doesn't compute anything new, it acts on the reachability state Endor already assigned to the finding.
Function Reachability
In addition to dependency reachability, Endor evaluates whether the specific vulnerable function inside the affected dependency is reachable from your application code. Endor assigns one of three function-level reachability tags based on what call graph analysis was able to prove.
The three function reachability states
Finding tag | What it means |
|---|---|
Reachable Function | Endor found a concrete static call path from one of your application's entry points to the specific vulnerable function. |
Unreachable Function | The vulnerable function is in the analyzed call graph, no call path reaches it from any entry point, and Endor has complete call graph coverage along the way. |
Potentially Reachable Function | Endor does not have enough evidence to claim Reachable Function or Unreachable Function. |
Common causes of a "Potentially Reachable Function" finding
A finding is tagged Potentially Reachable Function when any of the following is true:
Call graph coverage is incomplete along the path to the affected dependency. Some intermediate package between your code and the vulnerable dependency could not be analyzed — for example, it is in a language unsupported for call graph analysis, the artifact wasn't available, or the dependency was skipped due to scope. When that happens, "no path found" cannot be trusted as proof, so Endor degrades the result to Potentially Reachable.
The affected package itself has no call graph available. If Endor doesn't have the call graph for the package that contains the vulnerable function, it cannot look inside that package to make a definitive claim.
The vulnerability advisory does not identify specific affected functions. Some advisories only identify the affected package, not the affected symbols. With no symbol to trace, Endor cannot perform function-level analysis and tags the finding as Potentially Reachable.
The affected dependency is itself only Potentially Reachable. Function reachability is gated by dependency reachability. If Endor can't confirm the dependency is reachable, it can't confirm the function inside it is reachable either.
A vulnerability has multiple affected functions with mixed results. When several vulnerable symbols are listed for one advisory and the analysis is unsure about any of them, Endor errs on the side of caution and tags the finding as Potentially Reachable rather than Unreachable.
Call graph analysis is unsupported for the affected language or package manager.
How function reachability relates to action policies
The action policy filter for Function Reachability is built directly on top of these three finding tags:
"Reachable Function" → matches findings tagged Reachable Function.
"Unreachable Function" → matches findings tagged Unreachable Function.
"Potentially Reachable Function" → matches findings tagged Potentially Reachable Function.
The policy doesn't compute anything new — it acts on the reachability state Endor already assigned to the finding.
How dependency and function reachability work together
A single finding can carry both a dependency tag and a function tag. They answer different questions:
A finding tagged Reachable Dependency + Unreachable Function means your application uses the package, but no call path reaches the specific vulnerable function.
A finding tagged Reachable Dependency + Potentially Reachable Function means the package is in use, but Endor could not trace a path to the vulnerable symbol — or could not identify the symbol at all.
A finding tagged Potentially Reachable Dependency will not receive a definitive function reachability tag; function analysis depends on dependency reachability being confirmed first.
How to reduce "Potentially Reachable" findings
If you want more definitive Reachable/Unreachable answers and fewer Potentially Reachable findings:
Ensure your project's languages and package managers are supported by call graph analysis.
Scan after dependencies are installed and resolved.
Commit your lockfile to source control so Endor can build a complete dependency graph.
Sources: