Safeguard
Developer Tools•

What does GOTOOLCHAIN do, and will Go download a toolchain?

GOTOOLCHAIN decides whether the go command may switch to a newer Go toolchain it downloads and verifies. See the values, the default, and how to pin CI.

Safeguard Security Team
3 min read

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:

ValueBehavior
localAlways use the bundled toolchain
go1.21.0 (a name)Always use that toolchain, downloading and verifying it if not on PATH
autoShorthand for local+auto, the default in standard toolchains
pathShorthand for local+path
go1.21.3+autoStart with the named toolchain, may switch to a newer one, downloads allowed
go1.21.3+pathLike +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.
  • GOPRIVATE and GONOSUMDB do 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

  1. Decide which Go version your pipeline should use and bake it into the build image.
  2. Set GOTOOLCHAIN=local in the job so a go.mod change fails loudly instead of triggering a download.
  3. In a locked down network, also route GOPROXY to an internal mirror that carries toolchain modules, or the download path will not work.
  4. When a go.mod bump needs a newer Go, update the image deliberately, then merge.
  5. Record the toolchain version in your build provenance. go version in 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.

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.