Safeguard
Supply Chain•

Is every module in go.mod actually compiled into my Go binary?

No. Go compiles only packages your build imports, so a module listed in go.mod may add nothing to the binary. How that changes vulnerability triage.

Safeguard Security Team
3 min read

No. Go builds only the packages your code imports, directly or through other packages. A module can appear in go.mod or go.sum because of version selection and still contribute nothing to your binary. The Go team states that modules that do not contribute code to a build have no security impact on it.

Three different lists

People mix these up when triaging findings:

ListWhat it contains
go.modRequired modules, including indirect ones needed for version selection
Module graphEvery module and version requirement edge, from go mod graph
Binary build infoDependencies that contributed packages, from the compiled binary

The runtime/debug documentation says the binary's Deps field holds dependencies that contributed packages to the build. That is usually the smallest list.

Why a module can be in the graph but not the build

Go reads the go.mod of dependencies to compute versions. A module needed only for a package you never import, or only by tests of a dependency, is still listed. Also, the // indirect marker in go.mod shows requirements not imported directly by your module.

Two further factors shrink the list:

  • Build tags and target OS or architecture can exclude files.
  • Packages within a module are compiled separately, so a large module may contribute a single small package.

What this changes in vulnerability triage

A scanner that matches go.mod versions flags a module even if your binary has none of its code. A tool that reads the built binary, or that analyses which functions you call, narrows the list. The Go vulnerability documentation describes this call based approach for govulncheck.

Steps to apply it:

  1. Take the flagged module from your report.
  2. Run go mod why -m module to see whether your main module needs any package from it.
  3. Build the binary and check go version -m output for that module in the dependency list.
  4. If it is absent, record that finding as not present in the build, with the date and commit.
  5. If present, check whether a vulnerable function is reachable with govulncheck, then plan the fix.

Do not overcorrect

Absent today does not mean absent forever. A later import can pull the module in. Rescan on every dependency change. And your test binaries and tools may compile modules your release binary does not, which matters for developer machine security.

For the related question of reading what shipped, see reading dependencies from a compiled Go binary.

Try it yourself

Click through it at your own pace, or open it full screen. Watch how the list shrinks once only reachable code is counted.

Where Safeguard fits

Safeguard provides SBOM and dependency scanning with reachability analysis. Try a free scan on a Go repository.

Quick check

Does an indirect entry mean the code is in my binary?

Not necessarily. It means your module does not import it directly. Check the binary build info or run go mod why.

Can tests compile modules the release binary lacks?

Yes. Test and tool builds can pull in modules that your production binary never includes.

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.