golang/go · error

%s: invalid #cgo verb: %s

Error message

%s: invalid #cgo verb: %s

What it means

Final saveCgo failure: the verb token extracted from a #cgo line is not one of the recognized verbs CFLAGS, CPPFLAGS, CXXFLAGS, FFLAGS, LDFLAGS, or pkg-config. Reached at the default branch of the switch on `verb`. The %s fields are filename and the original line so the user can see the unknown verb.

Source

Thrown at src/cmd/go/internal/modindex/build.go:498

			// 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":
			di.CgoFFLAGS = append(di.CgoFFLAGS, args...)
		case "LDFLAGS":
			di.CgoLDFLAGS = append(di.CgoLDFLAGS, args...)
		case "pkg-config":
			di.CgoPkgConfig = append(di.CgoPkgConfig, args...)
		default:
			return fmt.Errorf("%s: invalid #cgo verb: %s", filename, orig)
		}
	}
	return nil
}

// expandSrcDir expands any occurrence of ${SRCDIR}, making sure
// the result is safe for the shell.
func expandSrcDir(str string, srcdir string) (string, bool) {
	// "\" delimited paths cause safeCgoName to fail
	// so convert native paths with a different delimiter
	// to "/" before starting (eg: on windows).
	srcdir = filepath.ToSlash(srcdir)

	chunks := strings.Split(str, "${SRCDIR}")
	if len(chunks) < 2 {
		return str, safeCgoName(str)
	}
	ok := true

View on GitHub (pinned to b6b368adc5)

Solutions

  1. Use one of the supported verbs: CFLAGS, CPPFLAGS, CXXFLAGS, FFLAGS, LDFLAGS, or pkg-config.
  2. Move unrelated compiler flags into CGO_* environment variables or your build system instead of // #cgo lines.
  3. For pkg-config dependencies use `#cgo pkg-config: foo bar`.

Example fix

// before
// #cgo LDLIBS: -lm
// after
// #cgo LDFLAGS: -lm
Defensive patterns

Strategy: validation

Validate before calling

// Validate cgo verbs before build.
var validCgoVerbs = map[string]bool{
    "CFLAGS": true, "CPPFLAGS": true, "CXXFLAGS": true,
    "FFLAGS": true, "LDFLAGS": true, "pkg-config": true,
}

func lintCgoVerbValue(line string) error {
    t := strings.TrimSpace(line)
    if !strings.HasPrefix(t, "#cgo") {
        return nil
    }
    head, _, _ := strings.Cut(strings.TrimPrefix(t, "#cgo"), ":")
    fields := strings.Fields(head)
    if len(fields) == 0 {
        return nil
    }
    if !validCgoVerbs[fields[len(fields)-1]] {
        return fmt.Errorf("unknown cgo verb %q", fields[len(fields)-1])
    }
    return nil
}

Prevention

When it happens

Trigger: Authoring a cgo directive with a typo'd or unsupported verb such as `#cgo LDLIBS: -lm`, `#cgo FLAGS: -O2`, or `#cgo GOTRACEBACK: 2`.

Common situations: Misspelling LDFLAGS as LDLIBS; assuming cgo supports arbitrary key/value pairs; using GCC-specific flags names that cgo does not recognize.

Related errors


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