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
- Move the cgo code into a non-test source file (e.g. helper.go) and call it from the test.
- Use a separate package (foo_test with cgo in foo.go) or an external test binary that shells out to a cgo-enabled helper.
- 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
- Keep all `import "C"` declarations in non-test .go files.
- Expose C-backed helpers from regular sources and consume them in tests.
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
- unclosed quote
- unfinished escaping
- CC not set and no default found
- multiple //go:build comments
- import cycle not allowed in test
AI-assisted analysis of golang/go@b6b368adc5 (2026-08-12).
Data as JSON: /api/errors/0ff0ec839ad10afb.
Report an issue: GitHub.