Safeguard
Supply Chain•

What does CGO_ENABLED=0 change for Go dependencies?

CGO_ENABLED=0 turns off cgo, so Go files that import C are skipped. Learn what that means for hidden C code in dependencies and for vulnerability scans.

Safeguard Security Team
3 min read

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

SituationSuggested setting
Static binary in a minimal image, no native needsCGO_ENABLED=0, then test
Needs a C library such as a database driverKeep cgo on, track the C library version
Cross compilingDefault is off, so set a cross compiler if you need cgo

Steps to check your own build

  1. Build once with cgo on and once with it off, and compare the outputs.
  2. Run your test suite under both settings.
  3. List the modules in the binary with go version -m, covered in read dependencies from a compiled Go binary.
  4. For any module that needs cgo, find which C library it wraps and where that library comes from.
  5. 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.

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.

Self-healing security runs on Safeguard.

Your first fix PR is minutes away.

No sales call required, even your agent can complete the purchase over MCP.