Safeguard
Security Guides•

Why does the same code get different reachability results per build?

Build flags, platforms and versions change which code is compiled, so reachability can differ between builds. Here is how to make results comparable.

Safeguard Security Team
3 min read

Reachability depends on which code is actually built. Operating system, architecture, language version, feature flags and tags can include or exclude whole files. So two builds of the same repository can have different call graphs, and a reachability result is only valid for the configuration that was analysed.

What the Go documentation says

The govulncheck documentation notes that results depend on a build configuration. For source analysis, that configuration includes the Go version and the target platform settings. For a compiled binary, it is the configuration used to build that binary, and it points out that different build configurations can produce different findings. This is a clear statement from a language team that the answer is not a property of the source alone.

Things that change the answer

  • Platform specific files. Code that handles Windows paths may never compile on Linux.
  • Feature flags and build tags. An optional module can be switched on in one image and off in another.
  • Language and runtime versions. Newer versions can swap in different standard library code.
  • Dependency resolution. A different resolved version of a transitive package changes the graph.
  • Conditional imports. Code that imports a package only when an environment variable is set.

How to make results comparable

  1. Analyse the configuration you ship, not a generic developer build.
  2. Record the configuration next to the result: version, platform, flags and the lockfile hash.
  3. If you ship several variants, such as Linux and Windows builds or a lite and full edition, analyse each.
  4. Rerun when any of those inputs change.
  5. Prefer analysing the built artifact when the tool supports it, since it reflects what really got compiled.

A simple record to keep

FieldExample
Artifactservice image, build number
Language versionthe exact toolchain
Platformoperating system and architecture
Flagslist of tags or options
Lockfile hashidentifier of resolved dependencies
Result and datereachable or not, date run

This record turns a vague "not reachable" into a statement that someone else can check and reproduce.

When this bites teams

A common story: the CI build runs on Linux, the product also ships a Windows installer, and the vulnerable function is in a Windows only path. The CI scan says not reachable, and it is right for Linux and wrong for Windows. Another: a feature flag is enabled for one customer tier only. The fix is to make the variants explicit in your scan matrix.

Safeguard includes reachability analysis alongside SBOM and dependency scanning, and you can run a free scan at gold.safeguard.sh/scan to see the output on your own repository.

Quick check

Is one reachability run enough for all my builds?

Only if all builds share the same configuration and resolved dependencies. Otherwise run per variant.

What is the cheapest improvement?

Store the build configuration with each result, so reviewers know what the answer covers.

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.