golang/go · error
FIPS 140-3 mode is incompatible with the purego build tag
Error message
FIPS 140-3 mode is incompatible with the purego build tag
What it means
Returned by fips140.Supported() when the purego build tag is active. FIPS 140-3 validation only covers the assembly-backed implementations; purego replaces too much crypto code with Go-level implementations, invalidating the validation boundary.
Source
Thrown at src/crypto/internal/fips140/fips140.go:38
case "on", "only":
Enabled = true
case "debug":
Enabled = true
debug = true
case "off", "":
default:
panic("fips140: unknown GODEBUG setting fips140=" + v)
}
}
// Supported returns an error if FIPS 140-3 mode can't be enabled.
func Supported() error {
// Keep this in sync with fipsSupported in cmd/dist/test.go.
// The purego tag changes too much of the implementation to claim the
// validation still applies.
if puregoEnabled {
return errors.New("FIPS 140-3 mode is incompatible with the purego build tag")
}
// ASAN disapproves of reading swaths of global memory in fips140/check.
// One option would be to expose runtime.asanunpoison through
// crypto/internal/fips140deps and then call it to unpoison the range
// before reading it, but it is unclear whether that would then cause
// false negatives. For now, FIPS+ASAN doesn't need to work.
if asanEnabled {
return errors.New("FIPS 140-3 mode is incompatible with ASAN")
}
// See EnableFIPS in cmd/internal/obj/fips.go for commentary.
// Also, js/wasm and windows/386 don't have good enough timers
// for the CPU jitter entropy source.
switch {
case runtime.GOARCH == "wasm",
runtime.GOOS == "windows" && runtime.GOARCH == "386",
runtime.GOOS == "openbsd", // due to -fexecute-only, see #70880View on GitHub (pinned to b6b368adc5)
Solutions
- Drop the purego build tag for the FIPS build target.
- Use a supported architecture (amd64, arm64, s390x) where assembly backends exist and purego is not required.
- If you need purego for portability, do not also enable FIPS mode — pick one.
- Audit GOFLAGS, makefiles, and Dockerfiles for stray -tags=purego.
Example fix
# before GOFLAGS="-tags=purego" GOFIPS140=1 go build ./... # after GOFIPS140=1 go build ./...
Defensive patterns
Strategy: validation
Validate before calling
if err := fips140.Supported(); err != nil {
if strings.Contains(err.Error(), "purego") {
log.Fatal("FIPS mode requires assembly backends; drop the purego build tag")
}
log.Fatalf("FIPS unsupported: %v", err)
} Try / catch
if err := fips140.Supported(); err != nil {
// surface at deploy time before serving traffic
return fmt.Errorf("refusing to start: FIPS mode unavailable: %w", err)
} Prevention
- Call fips140.Supported() at process startup and fail fast.
- Audit GOFLAGS, Dockerfiles, and CI for stray -tags=purego when FIPS is required.
- Build on a supported architecture so purego is unnecessary.
When it happens
Trigger: Building with -tags purego (or GOFLAGS containing it) and then calling fips140.Supported() or attempting to enable FIPS mode via GOFIPS140=1.
Common situations: Cross-compiling without assembly support; CI pipelines that add purego globally; tooling that injects purego for portability on unsupported architectures.
Related errors
- FIPS 140-3 mode is incompatible with ASAN
- FIPS 140-3 mode is incompatible with GOEXPERIMENT=boringcryp
- FIPS 140-3 mode is not supported on {GOOS}-{GOARCH}
- invalid signature
- ed25519: bad seed length: {l}
AI-assisted analysis of golang/go@b6b368adc5 (2026-08-12).
Data as JSON: /api/errors/db0186228f95efd3.
Report an issue: GitHub.