Safeguard
Security Guides•

How do you find which Go dependency pulls in a vulnerable module?

Use go mod why for the shortest import path and go mod graph for module edges to trace a vulnerable Go dependency to the module that requires it.

Safeguard Security Team
3 min read

Run go mod why -m example.com/module to see the shortest import path from your main module to a package in that module, and go mod graph to list which modules require which versions. Together they show who brought a vulnerable dependency in, so you know what to upgrade.

The two commands

According to the Go modules reference:

  • go mod why shows a shortest path in the import graph from the main module to each listed package. Each target gets a stanza starting with a # comment line. An unused target shows "(main module does not need package ...)". The -m flag treats arguments as modules.
  • go mod graph prints the module requirement graph, with replacements applied, one edge per line in the form path@version dependency@version. The main module has no version suffix.

They answer different questions:

QuestionCommand
Which of my packages imports this code?go mod why
Which module versions require this version?go mod graph
Is it even used in my build?go mod why

Steps to trace a finding

  1. Take the module and version from your scanner, for example a vulnerable example.com/lib at some version.
  2. Run go mod why -m example.com/lib. If it says the main module does not need the package, the module is only in the graph for version selection, which lowers urgency.
  3. If there is a path, read it top to bottom. The first hop after your module is the dependency you control.
  4. Run go mod graph and filter for the vulnerable module with grep to see every module that requires it, and at which version.
  5. Choose the fix: upgrade the direct dependency that drags in the old version, or require the fixed version yourself with go get example.com/lib@fixedversion.
  6. Rerun both commands and your scanner to confirm the old version is gone.

Why the graph can mislead

Go uses minimal version selection, so the version in your build is the highest minimum any module in the graph asks for. An edge in the graph to an old version does not mean that version is built. Check go list -m example.com/lib for the version actually selected.

Also remember that a module can be in go.mod without contributing code. The Go team's supply chain article notes that modules that do not contribute code to a specific build have no security impact on it.

Try it yourself

Click through it at your own pace, or open it full screen. Look for how a transitive package is tied back to the direct dependency that brought it in.

Where Safeguard fits

Safeguard's SBOM and dependency scanning show direct and transitive packages, and reachability analysis helps rank which findings matter. A free scan is a quick way to see it on your repository.

Quick check

Does go mod graph show the version that is built?

No. It shows requirement edges. Use go list -m to see the selected version.

What does go mod why print for an unused module?

It prints that the main module does not need the package.

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.