Since Go 1.21, the go line in go.mod sets a mandatory minimum version, and the toolchain line suggests one. The GOTOOLCHAIN setting decides whether the go command may switch to a newer toolchain automatically. The default is auto, so a module can pull your build onto a newer, patched Go without you installing anything.
The two lines in go.mod
The Go toolchain documentation explains that the go line is the minimum version needed to use the module. A toolchain older than that refuses to load it. The toolchain line names a suggested toolchain, and if omitted it is implied by the go version. A module's go line must be at least as high as the go line of every module it requires.
Before Go 1.21 the go line was advisory. The page notes that Go 1.19.13 and 1.20.8 were backported to refuse modules declaring Go 1.22 or later.
GOTOOLCHAIN values
| Value | Behavior |
|---|---|
| local | Always run the bundled toolchain |
| auto | Shorthand for local plus auto; the default for standard toolchains |
| path | Like auto, but only searches PATH and never downloads |
| a version name such as go1.21.0 | Always run that toolchain, downloading and verifying if needed |
The setting is read from the process environment, then the user default set with go env -w, then the go.env file in GOROOT. You can check it with go env GOTOOLCHAIN.
Why this matters for patching
With auto, if go.mod asks for a newer toolchain than the one installed, the go command runs the newer one, using a binary on PATH or downloading it. Downloaded toolchains are modules with the path golang.org/toolchain, honor GOPROXY and are checked against the checksum database.
That is a patching win: a repository that bumps its toolchain line to a fixed patch release gets every developer and CI job onto it on the next build.
It is also a control point. In a locked-down build agent, set GOTOOLCHAIN to local or path so builds fail loudly instead of downloading. Then you update the agent image on purpose.
A practical setup
- Commit a go line and a toolchain line that name the patch level you want.
- On laptops, leave GOTOOLCHAIN at auto.
- On build agents with restricted networks, use path or local and bake the Go version into the image.
- Move the toolchain line forward as part of regular dependency updates.
Commands like go get can change these lines for you. For example, go get toolchain@none removes the toolchain line, and go get go@1.25.0 also moves the toolchain line.
Watch for silent switches
When a newly added dependency requires a newer Go, the command prints a notice and switches. That is helpful, but review the resulting go.mod change in the pull request like any other change.
Safeguard's dependency scanning covers Go modules and can show which versions your repositories use. A free scan is at gold.safeguard.sh/scan.
Common mistakes
A few to avoid: leaving build agents on auto when they should not download anything, assuming the installed Go is the one that built your binary, and ignoring toolchain lines that change in a pull request. Print go version in CI logs so the answer is always visible.
Quick check
What is the default GOTOOLCHAIN?
Standard toolchains default to auto, which allows switching to a newer toolchain when go.mod requires one.
Can I stop Go from downloading toolchains?
Yes. Set GOTOOLCHAIN to local, or to path to search PATH only, and the go command will not download.
Sources
Last reviewed: 19 October 2026.