golang/go · error
%s: malformed #cgo argument: %s
Error message
%s: malformed #cgo argument: %s
What it means
Failure in saveCgo while expanding ${SRCDIR} placeholders in each cgo argument via expandSrcDir. The function returns ok=false when a chunk fails safeCgoName (i.e. contains characters unsafe to pass to the C compiler's shell, such as an unmatched quote or a backslash path separator on Windows). The offending (post-expansion) argument is printed.
Source
Thrown at src/cmd/go/internal/modindex/build.go:473
ok := false
for _, c := range cond {
if ctxt.matchAuto(c, nil) {
ok = true
break
}
}
if !ok {
continue
}
}
args, err := splitQuoted(argstr)
if err != nil {
return fmt.Errorf("%s: invalid #cgo line: %s", filename, orig)
}
for i, arg := range args {
if arg, ok = expandSrcDir(arg, di.Dir); !ok {
return fmt.Errorf("%s: malformed #cgo argument: %s", filename, arg)
}
args[i] = arg
}
switch verb {
case "CFLAGS", "CPPFLAGS", "CXXFLAGS", "FFLAGS", "LDFLAGS":
// Change relative paths to absolute.
ctxt.makePathsAbsolute(args, di.Dir)
}
switch verb {
case "CFLAGS":
di.CgoCFLAGS = append(di.CgoCFLAGS, args...)
case "CPPFLAGS":
di.CgoCPPFLAGS = append(di.CgoCPPFLAGS, args...)
case "CXXFLAGS":
di.CgoCXXFLAGS = append(di.CgoCXXFLAGS, args...)
case "FFLAGS":View on GitHub (pinned to b6b368adc5)
Solutions
- Convert all backslashes in cgo paths to forward slashes (`/`).
- Wrap ${SRCDIR} cleanly: `-I${SRCDIR}/include` with no stray quotes or shell metacharacters.
- Avoid shell operators (|, &, $ outside ${SRCDIR}, ;) in cgo arguments — they are passed verbatim.
Example fix
// before
// #cgo CFLAGS: -I${SRCDIR}\include
// after
// #cgo CFLAGS: -I${SRCDIR}/include Defensive patterns
Strategy: validation
Validate before calling
// Replicate safeCgoName's spirit: reject shell-unsafe chars in cgo args that contain ${SRCDIR}.
var safeCgoRe = regexp.MustCompile(`^[A-Za-z0-9_./+@%-]*$`)
func lintCgoSrcDir(arg string) error {
if !strings.Contains(arg, "${SRCDIR}") {
return nil
}
for _, chunk := range strings.Split(arg, "${SRCDIR}") {
if chunk != "" && !safeCgoRe.MatchString(chunk) {
return fmt.Errorf("unsafe chars around ${SRCDIR}: %q", arg)
}
}
return nil
} Prevention
- Use forward slashes only in cgo paths.
- Never embed shell metacharacters (|, &, ;, $) in cgo directives.
- On Windows, ensure ${SRCDIR} segments do not carry backslashes.
When it happens
Trigger: A cgo argument containing ${SRCDIR} where the surrounding text is unsafe for the shell, or an argument with a Windows-style backslash path that safeCgoName rejects. Reached when expandSrcDir returns ok=false.
Common situations: Hard-coding Windows paths like `#cgo CFLAGS: -I${SRCDIR}\include`; mixing backslashes with ${SRCDIR}; embedding shell metacharacters in a cgo flag.
Understand the failure class
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- %s: invalid #cgo line: %s
- %s: invalid #cgo verb: %s
- could not map %s symbol with no section
- could not map %s symbol with non .text or .rdata or .data se
- %s: invalid symbol binding %d
AI-assisted analysis of golang/go@b6b368adc5 (2026-08-12).
Data as JSON: /api/errors/056bf5426901d797.
Report an issue: GitHub.