golang/go · critical
should be something like "go1.12"
Error message
should be something like "go1.12"
What it means
The -lang flag tells the Go compiler which language version to target. The parseLang function validates the flag value against the regex ^go([1-9]\d*)\.(0|[1-9]\d*)$. If the value does not match, this error is returned. The accepted format is goMAJOR.MINOR (e.g. go1.21). The special value go1 is accepted and treated as go1.0. ParseLangFlag then calls log.Fatalf, making this a fatal error that aborts the compiler.
Source
Thrown at src/cmd/compile/internal/types/goversion.go:68
defVers, err := parseLang(def)
if err != nil {
log.Fatalf("internal error parsing default lang %q: %v", def, err)
}
if langWant.major > defVers.major || (langWant.major == defVers.major && langWant.minor > defVers.minor) {
log.Fatalf("invalid value %q for -lang: max known version is %q", base.Flag.Lang, def)
}
}
}
// parseLang parses a -lang option into a langVer.
func parseLang(s string) (lang, error) {
if s == "go1" { // cmd/go's new spelling of "go1.0" (#65528)
s = "go1.0"
}
matches := goVersionRE.FindStringSubmatch(s)
if matches == nil {
return lang{}, fmt.Errorf(`should be something like "go1.12"`)
}
major, err := strconv.Atoi(matches[1])
if err != nil {
return lang{}, err
}
minor, err := strconv.Atoi(matches[2])
if err != nil {
return lang{}, err
}
return lang{major: major, minor: minor}, nil
}
// currentLang returns the current language version.
func currentLang() string {
return fmt.Sprintf("go1.%d", goversion.Version)
}
// goVersionRE is a regular expression that matches the validView on GitHub (pinned to b6b368adc5)
Solutions
- Use the exact format goMAJOR.MINOR, e.g. -lang go1.21
- Set the version in go.mod instead: edit the go directive to 'go 1.21' and remove the -lang flag
- Remove the explicit -lang flag entirely and let go.mod control the language version
- Check that any version interpolation in build scripts produces the goMAJOR.MINOR format
Example fix
// before (Makefile) go build -lang 1.21 ./... // after (Makefile) go build -lang go1.21 ./...
Defensive patterns
Strategy: validation
Validate before calling
// Validate a -lang flag value matches the Go compiler's expected format
import (
"regexp"
)
var goLangRE = regexp.MustCompile(`^go([1-9]\d*)\.(0|[1-9]\d*)$`)
func validateLangFlag(lang string) error {
if lang == "" {
return nil // empty means unset, which is valid
}
if lang == "go1" {
return nil // special-cased as go1.0
}
if !goLangRE.MatchString(lang) {
return fmt.Errorf("invalid -lang value %q: expected format like go1.21", lang)
}
return nil
} Prevention
- Always use the goMAJOR.MINOR format for -lang (e.g., go1.21, not 1.21 or v1.21)
- Prefer setting the version in go.mod instead of passing -lang on the command line
- Validate interpolated version strings in build scripts before passing to -lang
- Document the expected -lang format in build script comments
When it happens
Trigger: Passing -lang with a value that does not match the regex. Invalid examples: 1.21 (missing go prefix), go1.21.0 (extra component), go01.21 (leading zero in major), v1.21 (v prefix), go1.x (non-numeric minor), go.21 (missing major). Note: go1 alone IS valid and is treated as go1.0.
Common situations: Build scripts or Makefiles that pass the version in semver format instead of Go format. CI configurations that interpolate a version variable into -lang without the go prefix. Confusing the -lang format with go.mod's go directive format (go.mod does not require the go prefix in some contexts).
Related errors
- go:embed requires go1.16 or later (-lang was set to %s; chec
- error opening profile: %w
- total length of command line and environment variables excee
- cipher: the nonce can't have zero length
- tls: no certificates configured
AI-assisted analysis of golang/go@b6b368adc5 (2026-08-12).
Data as JSON: /api/errors/44c7ef14a2ea18d1.
Report an issue: GitHub.