golang/go · error

invalid flag in %s: %s %s (see https://go.dev/s/invalidflag)

Error message

invalid flag in %s: %s %s (see https://go.dev/s/invalidflag)

What it means

Thrown by checkFlags (the `Bad`-adjacent block) when a flag that takes an argument (e.g. `-I`) is followed by a value that does not satisfy validation. The flag's next token is captured and reported as `invalid flag in <source>: <flag> <value>`, pointing at the source (a #cgo line or env var).

Source

Thrown at src/cmd/go/internal/work/security.go:460

					strings.HasPrefix(arg, "-Wl,") &&
					strings.HasPrefix(list[i+1], "-Wl,") &&
					load.SafeArg(list[i+1][4:]) &&
					!strings.Contains(list[i+1][4:], ",") {
					i++
					continue Args
				}

				// Permit -I= /path, -I $SYSROOT.
				if i+1 < len(list) && arg == "-I" {
					if (strings.HasPrefix(list[i+1], "=") || strings.HasPrefix(list[i+1], "$SYSROOT")) &&
						load.SafeArg(list[i+1][1:]) {
						i++
						continue Args
					}
				}

				if i+1 < len(list) {
					return fmt.Errorf("invalid flag in %s: %s %s (see https://go.dev/s/invalidflag)", source, arg, list[i+1])
				}
				return fmt.Errorf("invalid flag in %s: %s without argument (see https://go.dev/s/invalidflag)", source, arg)
			}
		}
	Bad:
		return fmt.Errorf("invalid flag in %s: %s (see https://go.dev/s/invalidflag)", source, arg)
	}
	return nil
}

View on GitHub (pinned to b6b368adc5)

Solutions

  1. Inspect the flagged flag/value pair reported in the error and fix the offending token.
  2. Ensure `-I`/`-L` paths are relative, well-formed, and pass load.SafeArg.
  3. Run `go build -x` to see the exact flag list before validation.
  4. Use CGO_CFLAGS_ALLOW (a valid regexp) only as a last-resort override.

Example fix

// before
// #cgo CFLAGS: -I ../../..

// after
// #cgo CFLAGS: -I ./include
Defensive patterns

Strategy: validation

Validate before calling

// Pre-check cgo flag/arg pairs for suspicious values
flags := strings.Fields(os.Getenv("CGO_CFLAGS"))
for i := 0; i+1 < len(flags); i++ {
    if flags[i] == "-I" || flags[i] == "-L" {
        if !load.SafeArg(flags[i+1]) { // mirror go's own check
            log.Fatalf("suspicious %s argument: %s", flags[i], flags[i+1])
        }
    }
}

Prevention

When it happens

Trigger: A #cgo CFLAGS line or CGO_CFLAGS entry like `-I -L` or `-I @file` where the argument is itself disallowed (e.g. unsafe per load.SafeArg, or matches an invalid pattern). checkFlags detects i+1 is in range and returns this two-token form.

Common situations: A vendored C library's #cgo line passes `-I` with a path containing shell metacharacters; CGO_CFLAGS crafted with a value flagged by SafeArg (absolute traversal, NUL bytes); copy-pasting gcc invocation snippets into #cgo verbatim.

Related errors


AI-assisted analysis of golang/go@b6b368adc5 (2026-08-12). Data as JSON: /api/errors/952eccf1984fc1fa. Report an issue: GitHub.