Go "go.mod requires go >= 1.XX (running go 1.YY; GOTOOLCHAIN=local)" in CI
The go directive sets a minimum toolchain. When GOTOOLCHAIN=local, Go will not download a newer one, so a runner Go below the required version fails instead of auto-upgrading.
What this error means
A go command fails with "go.mod requires go >= 1.22 (running go 1.21; GOTOOLCHAIN=local)" on a runner whose Go is older than the directive.
go
go: go.mod requires go >= 1.22 (running go 1.21.6; GOTOOLCHAIN=local)Common causes
The runner Go is older than the go directive
The module declares go 1.22 but the runner has 1.21, and GOTOOLCHAIN=local forbids fetching a newer toolchain.
GOTOOLCHAIN pinned to local in the environment
CI set GOTOOLCHAIN=local (or go1.21), disabling the automatic toolchain download that would otherwise satisfy the directive.
How to fix it
Install a runner Go that meets the directive
- Pin setup-go to at least the version the go directive requires.
- Re-run the build so the local toolchain satisfies it.
- This is the most reproducible fix for CI.
.github/workflows/ci.yml
- uses: actions/setup-go@v5
with:
go-version: '1.22'Allow automatic toolchain selection
Unset the local pin so Go may download the toolchain the directive needs.
Terminal
export GOTOOLCHAIN=auto
go build ./...How to prevent it
- Keep the CI Go version at or above the go directive.
- Decide deliberately between
GOTOOLCHAIN=localandautofor CI. - Bump the runner Go when you raise the go directive.
Related guides
Go "unknown directive" in go.mod in CIFix Go "go.mod: unknown directive: X" in CI - go.mod contains a directive this Go version does not understand…
Go "cannot range over n (variable of type int)" on an older toolchain in CIFix Go "cannot range over n (variable of type int)" in CI - ranging over an integer requires Go 1.22 or newer…
Go "usage: require module/path v1.2.3" malformed go.mod require in CIFix Go "go.mod: usage: require module/path v1.2.3" in CI - a require line is missing its version or has the w…