golang/go · error
go:embed requires go1.16 or later (-lang was set to %s; chec
Error message
go:embed requires go1.16 or later (-lang was set to %s; check go.mod)
What it means
The //go:embed directive was introduced in Go 1.16. The compiler checks the effective language version (derived from go.mod's go directive or the -lang compiler flag) via types.AllowsGoVersion(1, 16). If the version is below 1.16 and an embed directive is encountered on a var declaration, this error is returned with the current -lang value.
Source
Thrown at src/cmd/compile/internal/noder/noder.go:476
renameinitgen++
return s
}
func checkEmbed(decl *syntax.VarDecl, haveEmbed, withinFunc bool) error {
switch {
case !haveEmbed:
return errors.New("go:embed requires import \"embed\" (or import _ \"embed\", if package is not used)")
case len(decl.NameList) > 1:
return errors.New("go:embed cannot apply to multiple vars")
case decl.Values != nil:
return errors.New("go:embed cannot apply to var with initializer")
case decl.Type == nil:
// Should not happen, since Values == nil now.
return errors.New("go:embed cannot apply to var without type")
case withinFunc:
return errors.New("go:embed cannot apply to var inside func")
case !types.AllowsGoVersion(1, 16):
return fmt.Errorf("go:embed requires go1.16 or later (-lang was set to %s; check go.mod)", base.Flag.Lang)
default:
return nil
}
}
View on GitHub (pinned to b6b368adc5)
Solutions
- Update go.mod to go 1.16 or higher: edit the go directive to 'go 1.21' (or your toolchain version)
- Remove any explicit -lang compiler flag or set it to go1.16+
- If you cannot raise the language version, remove the embed directives and load files at runtime with os.ReadFile
Example fix
// before (go.mod) go 1.15 // after (go.mod) go 1.21
Defensive patterns
Strategy: validation
Validate before calling
// Check go.mod version supports embed before using it
import (
"os"
"strings"
)
func checkGoModVersion() (major, minor int, err error) {
data, err := os.ReadFile("go.mod")
if err != nil {
return 0, 0, err
}
for _, line := range strings.Split(string(data), "\n") {
line = strings.TrimSpace(line)
if strings.HasPrefix(line, "go ") {
v := strings.TrimPrefix(line, "go ")
parts := strings.Split(v, ".")
if len(parts) >= 2 {
fmt.Sscanf(parts[0], "%d", &major)
fmt.Sscanf(parts[1], "%d", &minor)
return major, minor, nil
}
}
}
return 0, 0, fmt.Errorf("no go directive in go.mod")
}
// Usage: ensure major > 1 || (major == 1 && minor >= 16) before using embed Prevention
- Always set go.mod's go directive to at least the version that introduced the features you use
- Keep go.mod's go directive updated when upgrading your Go toolchain
- Do not pass -lang explicitly in build scripts unless necessary — let go.mod control it
- Document minimum Go version requirements in your project README
When it happens
Trigger: A go.mod file declaring go 1.15 or lower combined with //go:embed directives in source files. Also triggered by explicitly passing -lang go1.15 (or lower) to the compiler while using embed directives.
Common situations: Adding embed directives to an existing project without updating go.mod's go directive. Working in a monorepo or vendored dependency where the language version is pinned below 1.16. CI pipelines that pass -lang explicitly.
Related errors
- should be something like "go1.12"
- invalid quoted string in //go:embed: %s
- error opening profile: %w
- not a regular file
- file changed between reads
AI-assisted analysis of golang/go@b6b368adc5 (2026-08-12).
Data as JSON: /api/errors/afec3d5294a6e466.
Report an issue: GitHub.