{"record":{"id":"e9a9ea6a1d140b89","repo":"golang/go","slug":"flag-q-triggers-external-linking","errorCode":null,"errorMessage":"flag %q triggers external linking","messagePattern":"flag %q triggers external linking","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/cmd/go/internal/work/security.go","lineNumber":339,"sourceCode":"\treturn checkFlags(name, source, list, nil, validPkgConfigFlags, nil, checkOverrides)\n}\n\n// checkCompilerFlagsForInternalLink returns an error if 'list'\n// contains a flag or flags that may not be fully supported by\n// internal linking (meaning that we should punt the link to the\n// external linker).\nfunc checkCompilerFlagsForInternalLink(name, source string, list []string) error {\n\tcheckOverrides := false\n\tif err := checkFlags(name, source, list, nil, validCompilerFlags, validCompilerFlagsWithNextArg, checkOverrides); err != nil {\n\t\treturn err\n\t}\n\t// Currently the only flag on the allow list that causes problems\n\t// for the linker is \"-flto\"; check for it manually here.\n\t// Also check for -static/--static, which some toolchains accept\n\t// as a compiler flag.\n\tfor _, fl := range list {\n\t\tif strings.HasPrefix(fl, \"-flto\") {\n\t\t\treturn fmt.Errorf(\"flag %q triggers external linking\", fl)\n\t\t}\n\t\tif fl == \"-static\" || fl == \"--static\" {\n\t\t\treturn fmt.Errorf(\"flag %q triggers external linking\", fl)\n\t\t}\n\t}\n\treturn nil\n}\n\n// checkLinkerFlagsForInternalLink returns an error if 'list'\n// contains linker flags that are not compatible with internal linking.\nfunc checkLinkerFlagsForInternalLink(name, source string, list []string) error {\n\tcheckOverrides := false\n\tif err := checkFlags(name, source, list, nil, validLinkerFlags, validLinkerFlagsWithNextArg, checkOverrides); err != nil {\n\t\treturn err\n\t}\n\t// Flags that force static linking require the external linker\n\t// to resolve libc symbols. See #77768.\n\tfor _, fl := range list {","sourceCodeStart":321,"sourceCodeEnd":357,"githubUrl":"https://github.com/golang/go/blob/b6b368adc57c96c3151d224d172029f233ead2c3/src/cmd/go/internal/work/security.go#L321-L357","documentation":"Thrown by checkCompilerFlagsForInternalLink when a compiler flag begins with `-flto` (link-time optimization) while the build is attempting internal (Go-only) linking. LTO embeds IR that only the external system linker can resolve, so the go command refuses it rather than silently falling back.","triggerScenarios":"Build a pure-Go or cgo package with internal linking while CGO_CFLAGS / CGO_LDFLAGS / a #cgo CFLAGS line contains `-flto`, `-flto=auto`, `-flto=thin`, etc. The HasPrefix(\"-flto\") branch in checkCompilerFlagsForInternalLink returns.","commonSituations":"Inheriting distro CFLAGS (`export CFLAGS=-flto`) that bleed into CGO_CFLAGS; a vendored C dependency that hard-codes `-flto` in its #cgo directive; CI that sets aggressive optimization env vars globally.","solutions":["Remove `-flto` from CGO_CFLAGS / the #cgo CFLAGS line and rebuild.","Allow external linking: add `-buildmode=pie` or build with cgo so the external linker is used (the flag is only blocked for internal linking).","Override the inherited CFLAGS: `CGO_CFLAGS='' go build`.","Find the source: `go build -x` prints the offending flag and which #cgo block contributed it."],"exampleFix":"// before\n// #cgo CFLAGS: -O2 -flto\n\n// after\n// #cgo CFLAGS: -O2","handlingStrategy":"validation","validationCode":"// Strip -flto* from CGO_CFLAGS before building\ncflags := os.Getenv(\"CGO_CFLAGS\")\nfiltered := cflags[:0]\nfor _, f := range strings.Fields(cflags) {\n    if !strings.HasPrefix(f, \"-flto\") {\n        filtered = append(filtered, f)\n    }\n}\nos.Setenv(\"CGO_CFLAGS\", strings.Join(filtered, \" \"))","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Avoid exporting CFLAGS=-flto globally in CI.","Audit #cgo CFLAGS lines in vendored C deps.","Prefer per-package CGO_CFLAGS over inherited env."],"tags":["go-toolchain","cgo","linker","lto","flags"],"backgroundTag":null,"analyzedSha":"b6b368adc57c96c3151d224d172029f233ead2c3","analyzedAt":"2026-08-12T00:22:02.250Z","schemaVersion":2},"datasetVersion":"2026-08-12T13:17:24.610Z"}