Largely, yes. Go uses minimal version selection, so each requirement in go.mod names a minimum version and the build picks the lowest set that satisfies them all, not the newest. A new release does not enter your build until someone raises a requirement. The go.sum file then checks content hashes.
How minimal version selection works
The Go modules reference describes it: Go uses an algorithm called minimal version selection to choose the module versions for a build. It works over a directed graph made from go.mod files. Each vertex is a module version, and each edge is a minimum required version from a require directive. The output is the build list.
The practical effect is different from ecosystems that resolve to the newest compatible version. In Go, publishing a new version of a dependency does not change your build by itself. You choose when to move.
What go.sum does
The reference says the go command authenticates downloaded content using go.sum files and, by default, the checksum database. If a hash is missing from go.sum, for example the first time a module is used, the go command checks it against the checksum database, unless the module path is matched by GOPRIVATE or GONOSUMDB.
That is a different thing from a lock file in other ecosystems. go.mod holds the minimum versions that define the build, while go.sum holds hashes that make sure what you download is what everybody else got.
go mod verify
The reference notes that go mod verify checks that module archives and extracted directories match the hashes recorded when they were first downloaded into the module cache. It detects changes to the cache, and it does not download content for modules that are not in the cache.
Where drift still comes from
Go is stable by default, but you can introduce movement yourself.
- An explicit upgrade, such as running go get with the update flag across all packages, raises minimum versions, and your go.mod then records the new ones.
- go mod tidy can change requirements when it removes a dependency that previously imposed one.
- Pseudo-versions point at commits. The reference says they must have a matching tag ancestor and timestamp, which limits abuse, but they still mean you track a commit, not a release.
- A checked in go.work file can cause CI to test the wrong versions, so the reference advises against committing it in most cases and says CI generally should not use it.
A routine that fits
- Commit go.mod and go.sum together, always.
- Review go.mod diffs in pull requests. A bumped minimum is a decision.
- Run go mod verify in CI.
- Treat GOPRIVATE and GONOSUMDB entries as exceptions you can name and justify, since they skip the public checksum database.
- Upgrade on a schedule, with tests, not in the middle of a feature branch.
Minimal does not mean current
Minimal version selection keeps you on the lowest versions that satisfy the graph, which can mean old versions with known vulnerabilities. Stability and freshness pull against each other, so you need a process that raises minimums when a fix is available.
Where Safeguard fits
Safeguard's dependency scanning and SBOM generation can check the versions your Go module graph selects against known vulnerabilities, and reachability analysis helps show which findings your code can actually call. A free scan is at gold.safeguard.sh/scan.
Try it yourself
Open the demo and compare the full list of findings with the ones your code can actually reach.
Click through it at your own pace, or open it full screen.
Quick check
Do I need to commit go.sum?
Yes, commit it with go.mod. It records the hashes the go command uses to authenticate downloaded modules.
Does Go ever pick the newest version automatically?
Not through minimal version selection. It selects the minimum versions that satisfy the requirements, and you raise them explicitly.
Sources
Last reviewed: 19 October 2026.