golang/go · error

use of cgo in test %s not supported

Error message

use of cgo in test %s not supported

What it means

Recorded as a bad-Go-file error during IndexPackage.Import when a _test.go file imports the pseudo-package "C". cgo in test files is intentionally unsupported by the build system; the offending file is added to InvalidGoFiles and the error is propagated at the end of Import. The %s is the test file name.

Source

Thrown at src/cmd/go/internal/modindex/read.go:590

				Dir:      p.Dir,
				Packages: []string{p.Name, pkg},
				Files:    []string{firstFile, name},
			})
		}
		// Grab the first package comment as docs, provided it is not from a test file.
		if p.Doc == "" && !isTest && !isXTest {
			if synopsis := tf.synopsis(); synopsis != "" {
				p.Doc = synopsis
			}
		}

		// Record Imports and information about cgo.
		isCgo := false
		imports := tf.imports()
		for _, imp := range imports {
			if imp.path == "C" {
				if isTest {
					badGoFile(name, fmt.Errorf("use of cgo in test %s not supported", name))
					continue
				}
				isCgo = true
			}
		}
		if directives := tf.cgoDirectives(); directives != "" {
			if err := ctxt.saveCgo(name, p, directives); err != nil {
				badGoFile(name, err)
			}
		}

		var fileList *[]string
		var importMap, embedMap map[string][]token.Position
		var directives *[]build.Directive
		switch {
		case isCgo:
			allTags["cgo"] = true
			if ctxt.CgoEnabled {

View on GitHub (pinned to b6b368adc5)

Solutions

  1. Move the cgo code into a non-test source file (e.g. helper.go) and call it from the test.
  2. Use a separate package (foo_test with cgo in foo.go) or an external test binary that shells out to a cgo-enabled helper.
  3. For testing C interop, build a small cgo helper binary via go test with a non-_test.go cgo file in the same package.

Example fix

// before (foo_test.go)
package foo_test
// #cgo LDFLAGS: -lm
import "C"
// after: move cgo into helper.go (non-test), call from foo_test.go
Defensive patterns

Strategy: validation

Validate before calling

// Scan _test.go files for `import "C"` before build.
func noCgoInTests(pkgDir string) error {
    entries, _ := os.ReadDir(pkgDir)
    for _, e := range entries {
        if !strings.HasSuffix(e.Name(), "_test.go") { continue }
        b, _ := os.ReadFile(filepath.Join(pkgDir, e.Name()))
        if bytes.Contains(b, []byte(`"C"`)) && bytes.Contains(b, []byte("import")) {
            return fmt.Errorf("%s: cgo is not allowed in test files", e.Name())
        }
    }
    return nil
}

Prevention

When it happens

Trigger: A *_test.go file contains `import "C"` (and typically associated // #cgo directives). Reached from the imports loop in Import when imp.path == "C" && isTest.

Common situations: Refactoring production cgo code into a _test.go to exercise C functions; copy-pasting a cgo source file and renaming it to a test file; writing CGo-based integration tests.

Related errors


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