Yes, by default the go command can download a newer Go toolchain when your go.mod requires one. The GOTOOLCHAIN setting controls this. The default is auto, which means the bundled toolchain plus switching on demand. Set local to forbid downloads, or a version name to force one.
The values
From the Go toolchain documentation:
| Value | Behavior |
|---|---|
| local | Always use the bundled toolchain |
| go1.21.0 (a name) | Always use that toolchain, downloading and verifying it if not on PATH |
| auto | Shorthand for local+auto, the default in standard toolchains |
| path | Shorthand for local+path |
| go1.21.3+auto | Start with the named toolchain, may switch to a newer one, downloads allowed |
| go1.21.3+path | Like +auto but searches only PATH, no download fallback |
If $GOROOT/go.env does not set a default, the go command assumes local. Precedence runs from the process environment, to the user default set with go env -w, to go.env.
How downloads are protected
Toolchains are downloaded as modules named golang.org/toolchain, with versions like v0.0.1-go1.21.0.linux-amd64. Downloads go through GOPROXY and are verified by the Go checksum database, like other modules.
Three details matter for security teams:
- Checksums are not written to go.sum, because the right toolchain depends on the local system.
- With
GOSUMDB=off, toolchain downloads fail for lack of verification. GOPRIVATEandGONOSUMDBdo not apply to toolchain downloads.
What triggers a switch
Since Go 1.21 the go line in go.mod is a mandatory minimum. A toolchain refuses to load a module that declares a newer Go version than its own, and with auto it fetches a newer toolchain instead. A toolchain line can suggest a specific one.
That means a pull request that bumps the go line can change which compiler builds your release, without anyone editing the CI image.
Steps to pin CI
- Decide which Go version your pipeline should use and bake it into the build image.
- Set
GOTOOLCHAIN=localin the job so a go.mod change fails loudly instead of triggering a download. - In a locked down network, also route
GOPROXYto an internal mirror that carries toolchain modules, or the download path will not work. - When a go.mod bump needs a newer Go, update the image deliberately, then merge.
- Record the toolchain version in your build provenance.
go versionin the job log is the minimum.
Teams that want convenience on developer machines can keep auto locally and use local only in CI.
Where Safeguard fits
Safeguard's policies and gates can hold a pull request that changes build inputs, and its SBOM and dependency scanning cover your module graph. Try a free scan.
Quick check
What is the default GOTOOLCHAIN?
auto, which is shorthand for local+auto, set in $GOROOT/go.env of standard toolchains.
Are downloaded toolchains verified?
Yes, through the Go checksum database, but their checksums are not stored in go.sum.
Sources
Last reviewed: 19 October 2026.