Safeguard
Supply Chain•

Why does my Go project have two versions of one module (v2 suffix)?

Go treats module/v2 as a separate module from module, so both can sit in one build. Why that happens and how to make sure each copy gets patched.

Safeguard Security Team
3 min read

Go treats a module at v2 or higher as a different module from the v1 path, because the major version is part of the module path. A build can therefore include example.com/mod and example.com/mod/v2 at the same time, and each one needs its own security check.

The rule

The Go reference states that starting with major version 2, module paths must carry a suffix such as /v2 that matches the major version. A module at example.com/mod v1.0.0 must be example.com/mod/v2 at v2.0.0. Suffixes are not allowed at v0 or v1.

Two special cases come up in real projects:

  • Paths that start with gopkg.in must always have a suffix, even at v0 and v1, and it starts with a dot, as in gopkg.in/yaml.v2.
  • A v2 or later version without a go.mod file shows up as a plus incompatible version, such as v4.1.2+incompatible.

Why two versions can coexist

The reference explains that modules with distinct suffixes are treated as separate modules, and their packages are distinct. That lets one dependency stay on the old major version while another uses the new one.

For security, this has a plain consequence. A fix in the v2 line does not fix the v1 copy in your build. If an advisory covers both lines, you may need to act on each path.

How to see what you actually have

go list -m all

Look for the same base path appearing with and without a suffix. Then ask who needs the old one:

go mod why -m example.com/mod

The command prints a path from your main module to a package in that module.

Decision table

SituationWhat to do
Your code imports the old major versionPlan a migration to the new import path
Only a dependency imports the old versionUpgrade that dependency, or ask its maintainers
Old version is plus incompatibleCheck whether a proper module version exists
Advisory lists only one major lineConfirm the other line is not affected before closing

What scanners must get right

A scanner should keep the major version suffix as part of the module name when it matches advisories. If it strips the suffix, it can attach a v1 advisory to a v2 module or miss a real match. When you evaluate a tool, test it on a project that has both lines and see whether each is reported separately.

Try it yourself

Click through it at your own pace, or open it full screen.

Look at how the inventory lists one package name at several versions, and what you would need to know to patch each.

Quick check

Is example.com/mod/v2 the same module as example.com/mod?

No. The Go reference treats distinct suffixes as separate modules with distinct packages.

Does upgrading to v2 fix a flaw in the v1 copy that another dependency still uses?

No. The v1 copy stays in the build until nothing requires it, so patch or replace that path too.

Safeguard's SBOM and dependency scanning gives you the component list to check this on. Run the free scan on a repository to see it.

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.