golangci/golangci-lint · error

cgo preprocessing failed

Error message

cgo preprocessing failed

What it means

When loading packages, a 'C' pseudo-package import means cgo preprocessing should have produced generated Go code. go/packages does not report cgo preprocessing failures, so the runner detects the raw C import during type checking and throws this error to signal that cgo failed before parsing. It is an internal safeguard in the loader's importer.

Solutions

  1. Run 'go build' on the failing package to see the real cgo error and fix it (missing header, bad directive)
  2. Verify a C compiler is installed and CGO_ENABLED=1 (unset CGO_ENABLED=0)
  3. Clear the build cache with 'go clean -cache' and retry
  4. Install missing C libraries/pkg-config files referenced by #cgo directives

Example fix

// before
CGO_ENABLED=0 golangci-lint run

// after
CGO_ENABLED=1 golangci-lint run
Defensive patterns

Strategy: validation

Validate before calling

if out, err := exec.Command("go", "build", "./...").CombinedOutput(); err != nil {
    return fmt.Errorf("fix build before linting (cgo issue?): %v\n%s", err, out)
}

Try / catch

if strings.Contains(err.Error(), "cgo preprocessing failed") {
    // ensure CGO_ENABLED=1 and a C compiler is available, then retry
}

Prevention

When it happens

Trigger: A package imports "C" but cgo preprocessing failed (missing C headers, invalid cgo directives, CGO_ENABLED issues, missing C compiler), so the raw C file content is encountered during type resolution.

Common situations: Building cgo code in environments without gcc/clang; missing #cgo pkg-config dependencies or headers; CGO_ENABLED=0 while analyzing cgo packages; corrupted build cache after toolchain changes.

Related errors


AI-assisted analysis of golangci/golangci-lint@ed7a235d2d (2026-09-02). Data as JSON: /api/errors/dd6331df1d0739ee. Report an issue: GitHub.

Appendix: source

Thrown at pkg/goanalysis/runner_loadingpackage.go:176

		Types:        make(map[ast.Expr]types.TypeAndValue),
		Instances:    make(map[*ast.Ident]types.Instance),
		Defs:         make(map[*ast.Ident]types.Object),
		Uses:         make(map[*ast.Ident]types.Object),
		Implicits:    make(map[ast.Node]types.Object),
		Selections:   make(map[*ast.SelectorExpr]*types.Selection),
		Scopes:       make(map[ast.Node]*types.Scope),
		FileVersions: make(map[*ast.File]string),
	}

	importer := func(path string) (*types.Package, error) {
		if path == unsafePkgName {
			return types.Unsafe, nil
		}
		if path == "C" {
			// go/packages doesn't tell us that cgo preprocessing
			// failed. When we subsequently try to parse the package,
			// we'll encounter the raw C import.
			return nil, errors.New("cgo preprocessing failed")
		}
		imp := pkg.Imports[path]
		if imp == nil {
			return nil, nil
		}
		if len(imp.Errors) > 0 {
			return nil, imp.Errors[0]
		}
		return imp.Types, nil
	}

	var goVersion string
	if pkg.Module != nil && pkg.Module.GoVersion != "" {
		goVersion = "go" + strings.TrimPrefix(pkg.Module.GoVersion, "go")
	} else {
		var err error
		goVersion, err = goutil.CleanRuntimeVersion()
		if err != nil {

View on GitHub (pinned to ed7a235d2d)