CGO_ENABLED=0 disables cgo, so the go tool skips any file that imports "C". Dependencies that need C code either fall back to pure Go files or fail to build. It can shrink the native code you ship, but it does not remove your duty to check what actually got compiled.
How cgo is switched on and off
The cgo documentation says it is enabled by default for native builds on systems where it is expected to work. It is disabled by default when cross compiling, and when the CC variable is unset and no default C compiler can be found on the path.
You can override the default by setting CGO_ENABLED to 1 or 0. When cgo is enabled, the go tool sets the build constraint "cgo". The special import "C" implies that constraint, so with cgo disabled, files that import "C" are not built.
What this means for a dependency
A Go module can carry both a cgo file and a pure Go file for the same job, selected by build tags. With cgo off, the pure Go file is used. If the module has only a cgo version, the build fails or the feature is missing.
So the setting can change which source files of a dependency are compiled. It does not change which modules are listed in go.mod.
Why security teams care
Cgo links Go code to C libraries, and C code brings memory safety bugs that Go otherwise avoids. A pure Go build removes the C part of that risk for the modules that offer a fallback. Static and distroless images often rely on this.
There is a catch for scanning. A vulnerability in a C library bundled inside a Go module may not appear in Go advisories at all. We explain the wider pattern in bundled native code in language packages.
Decision guide
| Situation | Suggested setting |
|---|---|
| Static binary in a minimal image, no native needs | CGO_ENABLED=0, then test |
| Needs a C library such as a database driver | Keep cgo on, track the C library version |
| Cross compiling | Default is off, so set a cross compiler if you need cgo |
Steps to check your own build
- Build once with cgo on and once with it off, and compare the outputs.
- Run your test suite under both settings.
- List the modules in the binary with
go version -m, covered in read dependencies from a compiled Go binary. - For any module that needs cgo, find which C library it wraps and where that library comes from.
- Record the setting in your build files so it is not left to the machine default.
Where Safeguard fits
Safeguard's dependency scanning and SBOM generation work from your Go manifests, and reachability analysis helps separate findings that your code can actually reach. Try the free scan at gold.safeguard.sh/scan.
Quick check
Does CGO_ENABLED=0 remove modules from go.mod?
No. It changes which files are built, not which modules are required.
Is cgo on by default?
For native builds on supported systems, yes. It is off by default when cross compiling or when no C compiler is found and CC is unset.
Sources
Last reviewed: 19 October 2026.