Skip to main content

Introduction

Go’s emphasis on backwards compatibility is one of its key strengths. However, there are times when we cannot maintain complete compatibility. If code depends on buggy (including insecure) behavior, then fixing the bug will break that code.
GODEBUG provides a mechanism to reduce the impact that behavior changes have on Go developers using newer toolchains to compile old code.
A GODEBUG setting is a key=value pair that controls the execution of certain parts of a Go program. The environment variable GODEBUG can hold a comma-separated list of these settings.

Basic Usage

If a Go program is running in an environment that contains:
GODEBUG=http2client=0,http2server=0
Then that Go program will disable the use of HTTP/2 by default in both the HTTP client and the HTTP server.
Unrecognized settings in the GODEBUG environment variable are ignored.

Setting GODEBUG

GODEBUG=http2client=0 ./myprogram

Default GODEBUG Values

When a GODEBUG setting is not listed in the environment variable, its value is derived from three sources:
1

Toolchain defaults

The defaults for the Go toolchain used to build the program
2

go.mod version

Amended to match the Go version listed in go.mod
3

//go:debug directives

Overridden by explicit //go:debug lines in the program

Example: panicnil Setting

Go 1.21 introduces the panicnil setting, controlling whether panic(nil) is allowed. It defaults to panicnil=0, making panic(nil) a run-time error. When a Go 1.21 toolchain compiles a program, if the work module’s go.mod says go 1.20, then the program defaults to panicnil=1, matching Go 1.20 instead of Go 1.21.

Using godebug Directives

Starting in Go 1.23, the work module’s go.mod or workspace’s go.work can list one or more godebug lines:
godebug (
    default=go1.21
    panicnil=1
    asynctimerchan=0
)
The special key default indicates a Go version to take unspecified settings from. This allows setting the GODEBUG defaults separately from the Go language version in the module.

Using //go:debug Directives

Starting in Go 1.21, a main package’s source files can include one or more //go:debug directives at the top of the file:
//go:debug default=go1.21
//go:debug panicnil=1
//go:debug asynctimerchan=0

package main
Go 1.21+ treats a //go:debug directive with an unrecognized GODEBUG setting as an invalid program. Programs with more than one //go:debug line for a given setting are also invalid.

Runtime Metrics

When possible, each GODEBUG setting has an associated runtime/metrics counter named /godebug/non-default-behavior/<name>:events that counts the number of times a particular program’s behavior has changed based on a non-default value. For example, when GODEBUG=http2client=0 is set, /godebug/non-default-behavior/http2client:events counts the number of HTTP transports that the program has configured without HTTP/2 support.

GODEBUG History

GODEBUG settings are introduced when behavior changes and maintained for a minimum of two years (four Go releases). Some settings are maintained much longer or indefinitely.

Go 1.27

Go 1.27 removed the gotypesalias setting.

Go 1.26

Controls the maximum number of query parameters that net/url will accept.
  • Default: urlmaxqueryparams=10000
  • Setting to 0 disables the limit
  • Backported to Go 1.25.6 and Go 1.24.12
Controls whether net/url.Parse allows malformed hostnames containing colons.
  • Default: urlstrictcolons=1 (rejects http://localhost:1:2)
  • Colons permitted in bracketed IPv6 addresses like http://[::1]/
Enables additional post-quantum key exchange mechanisms: SecP256r1MLKEM768 and SecP384r1MLKEM1024.
  • Default: Enabled
  • Revert with tlssecpmlkem=0
Controls inclusion of goroutine labels set through runtime/pprof in tracebacks.
  • Default: tracebacklabels=0
  • Enable with tracebacklabels=1
Controls whether most crypto/* APIs ignore the random io.Reader parameter.
  • Default: cryptocustomrand=0 (ignores random parameters)
  • Use cryptocustomrand=1 for pre-Go 1.26 behavior

Go 1.25

Controls whether the Go runtime annotates OS anonymous memory mappings (Linux only).
  • Default: decoratemappings=1
  • Annotations appear in /proc/self/maps as “[anon: Go: …]”
  • Fixed at program startup time
Controls whether the Go runtime considers cgroup CPU limits for GOMAXPROCS (Linux only).
  • Default: containermaxprocs=1 (use cgroup limits)
  • Set to 0 to disable
Controls whether the Go runtime periodically updates GOMAXPROCS for new CPU affinity or cgroup limits.
  • Default: updatemaxprocs=1 (enable periodic updates)
  • Set to 0 to disable
Go 1.25 disabled SHA-1 signature algorithms in TLS 1.2 per RFC 9155.
  • Default: SHA-1 disabled
  • Use tlssha1=1 to revert
Go 1.25 switched to SHA-256 for missing SubjectKeyId in crypto/x509.CreateCertificate.
  • Default: SHA-256
  • Use x509sha256skid=0 to revert to SHA-1
Go 1.25 RC 2 disabled build information stamping when multiple VCS are detected.
  • Default: Disabled
  • Use allowmultiplevcs=1 to re-enable
  • Backported to Go 1.24.5 and Go 1.23.11

Go 1.24

Controls whether the Go Cryptographic Module operates in FIPS 140-3 mode.
  • "off": No FIPS 140-3 support (default)
  • "on": FIPS 140-3 mode enabled
  • "only": Like “on”, but non-approved algorithms return errors
  • Fixed at program startup time
Go 1.24 changed global math/rand.Seed to be a no-op.
  • Default: randseednop=1 (no-op)
  • Use randseednop=0 for pre-Go 1.24 behavior
Controls MPTCP on dialers and listeners.
  • "0": Disable MPTCP on dialers and listeners
  • "1": Enable MPTCP on dialers and listeners
  • "2": Enable MPTCP on listeners only (default for Go 1.24)
  • "3": Enable MPTCP on dialers only
Go 1.24 changed go test -json to emit build errors as JSON.
  • Default: JSON format
  • Use gotestjsonbuildtext=1 for Go 1.23 text format
  • Will be removed in Go 1.28 at the earliest
Go 1.24 requires RSA keys to be at least 1024 bits.
  • Default: 1024-bit minimum
  • Use rsa1024min=0 for Go 1.23 behavior
Enables platform-specific DIT modes (currently arm64 only).
  • Default: dataindependenttiming=0
  • Use dataindependenttiming=1 to enable
Go 1.24 enabled X25519MLKEM768 by default.
  • Default: Enabled
  • Use tlsmlkem=0 to disable (useful for buggy TLS servers)
Go 1.24 made ParsePKCS1PrivateKey use and validate CRT parameters.
  • Default: Validate CRT parameters
  • Use x509rsacrt=0 for Go 1.23 behavior

Go 1.23

Go 1.23 changed time package channels to be unbuffered (synchronous).
  • Default: Unbuffered channels
  • Use asynctimerchan=1 for buffered channels
  • Will be removed in Go 1.27
Changed os.Readlink and filepath.EvalSymlinks to avoid normalizing volumes to drive letters.
  • Default: winreadlinkvolume=1
Go 1.23 removed 3DES cipher suites from default TLS configuration.
  • Default: 3DES disabled
  • Use tls3des=1 to revert
  • Will be removed in Go 1.27
Go 1.23 changed tls.X509KeyPair and tls.LoadX509KeyPair to populate the Leaf field.
  • Default: x509keypairleaf=1
  • Will be removed in Go 1.27

Go 1.22

Limits maximum acceptable RSA key size in TLS handshakes.
  • Default: tlsmaxrsasize=8192
  • Backported to Go 1.19.13, 1.20.8, and 1.21.1
Made it an error for requests/responses to have empty Content-Length headers.
  • Default: Strict validation
  • Use httplaxcontentlength=1 to allow empty headers
Changed ServeMux to accept extended patterns and unescape paths by segment.
  • Default: New behavior
  • Use httpmuxgo121=1 for Go 1.21 behavior
Added Alias type to go/types for explicit type alias representation.
  • Go 1.22 default: gotypesalias=0
  • Go 1.23+ default: gotypesalias=1
  • Removed in Go 1.27
Changed default minimum TLS version to TLS 1.2.
  • Default: TLS 1.2 minimum
  • Use tls10server=1 to revert to TLS 1.0
  • Will be removed in Go 1.27
Controls interaction with transparent huge pages on Linux.
  • Use disablethp=1 to disable THP for Go memory
  • Available starting Go 1.21.6
  • May be removed in future release

Go 1.21 and Earlier

Made it a run-time error to call panic with a nil interface value.
  • Default: Error on panic(nil)
  • No plan to remove this setting
Added support for Multipath TCP (opt-in).
  • Default: Disabled unless explicitly requested
  • No plan to remove this setting
Automatic seeding of global math/rand generator.
  • Default: Auto-seed enabled
  • No plan to remove this setting
Made it an error for path lookups to resolve to binaries in current directory.
  • Default: Error on current directory lookups
  • No plan to remove this setting
Controls transparent HTTP/2 support.
  • Default: HTTP/2 enabled
  • Set to 0 to disable
  • No plan to remove these settings
Controls whether to use pure Go DNS resolver or system resolver.
  • Platform-dependent default
  • No plan to remove this setting

Best Practices

Test new versions

Test your code with new Go versions without GODEBUG first to ensure forward compatibility.

Minimize GODEBUG use

Use GODEBUG settings as temporary migration aids, not permanent solutions.

Document usage

If you must use GODEBUG, document why and plan to remove it before the setting is retired.

Monitor metrics

Use runtime/metrics counters to track when non-default behaviors are triggered.

Update dependencies

Keep dependencies updated to avoid relying on old behavior.

Plan for removal

Remember that GODEBUG settings are maintained for only 2+ years (4 releases).

Checking Default GODEBUG Values

The defaults that will be compiled into a main package are reported by:
go list -f '{{.DefaultGODEBUG}}' my/main/package
Only differences from the base Go toolchain defaults are reported.

Language Specification

Complete Go language reference

Effective Go

Best practices and idiomatic patterns

Memory Model

Concurrency and synchronization guarantees

Build docs developers (and LLMs) love