1--- 2title: "Go, Backwards Compatibility, and GODEBUG" 3layout: article 4--- 5 6<!-- 7This document is kept in the Go repo, not x/website, 8because it documents the full list of known GODEBUG settings, 9which are tied to a specific release. 10--> 11 12## Introduction {#intro} 13 14Go's emphasis on backwards compatibility is one of its key strengths. 15There are, however, times when we cannot maintain complete compatibility. 16If code depends on buggy (including insecure) behavior, 17then fixing the bug will break that code. 18New features can also have similar impacts: 19enabling the HTTP/2 use by the HTTP client broke programs 20connecting to servers with buggy HTTP/2 implementations. 21These kinds of changes are unavoidable and 22[permitted by the Go 1 compatibility rules](/doc/go1compat). 23Even so, Go provides a mechanism called GODEBUG to 24reduce the impact such changes have on Go developers 25using newer toolchains to compile old code. 26 27A GODEBUG setting is a `key=value` pair 28that controls the execution of certain parts of a Go program. 29The environment variable `GODEBUG` 30can hold a comma-separated list of these settings. 31For example, if a Go program is running in an environment that contains 32 33 GODEBUG=http2client=0,http2server=0 34 35then that Go program will disable the use of HTTP/2 by default in both 36the HTTP client and the HTTP server. 37It is also possible to set the default `GODEBUG` for a given program 38(discussed below). 39 40When preparing any change that is permitted by Go 1 compatibility 41but may nonetheless break some existing programs, 42we first engineer the change to keep as many existing programs working as possible. 43For the remaining programs, 44we define a new GODEBUG setting that 45allows individual programs to opt back in to the old behavior. 46A GODEBUG setting may not be added if doing so is infeasible, 47but that should be extremely rare. 48 49GODEBUG settings added for compatibility will be maintained 50for a minimum of two years (four Go releases). 51Some, such as `http2client` and `http2server`, 52will be maintained much longer, even indefinitely. 53 54When possible, each GODEBUG setting has an associated 55[runtime/metrics](/pkg/runtime/metrics/) counter 56named `/godebug/non-default-behavior/<name>:events` 57that counts the number of times a particular program's 58behavior has changed based on a non-default value 59for that setting. 60For example, when `GODEBUG=http2client=0` is set, 61`/godebug/non-default-behavior/http2client:events` 62counts the number of HTTP transports that the program 63has configured without HTTP/2 support. 64 65## Default GODEBUG Values {#default} 66 67When a GODEBUG setting is not listed in the environment variable, 68its value is derived from three sources: 69the defaults for the Go toolchain used to build the program, 70amended to match the Go version listed in `go.mod`, 71and then overridden by explicit `//go:debug` lines in the program. 72 73The [GODEBUG History](#history) gives the exact defaults for each Go toolchain version. 74For example, Go 1.21 introduces the `panicnil` setting, 75controlling whether `panic(nil)` is allowed; 76it defaults to `panicnil=0`, making `panic(nil)` a run-time error. 77Using `panicnil=1` restores the behavior of Go 1.20 and earlier. 78 79When compiling a work module or workspace that declares 80an older Go version, the Go toolchain amends its defaults 81to match that older Go version as closely as possible. 82For example, when a Go 1.21 toolchain compiles a program, 83if the work module's `go.mod` or the workspace's `go.work` 84says `go` `1.20`, then the program defaults to `panicnil=1`, 85matching Go 1.20 instead of Go 1.21. 86 87Because this method of setting GODEBUG defaults was introduced only in Go 1.21, 88programs listing versions of Go earlier than Go 1.20 are configured to match Go 1.20, 89not the older version. 90 91To override these defaults, starting in Go 1.23, the work module's `go.mod` 92or the workspace's `go.work` can list one or more `godebug` lines: 93 94 godebug ( 95 default=go1.21 96 panicnil=1 97 asynctimerchan=0 98 ) 99 100The special key `default` indicates a Go version to take unspecified 101settings from. This allows setting the GODEBUG defaults separately 102from the Go language version in the module. 103In this example, the program is asking for Go 1.21 semantics and 104then asking for the old pre-Go 1.21 `panic(nil)` behavior and the 105new Go 1.23 `asynctimerchan=0` behavior. 106 107Only the work module's `go.mod` is consulted for `godebug` directives. 108Any directives in required dependency modules are ignored. 109It is an error to list a `godebug` with an unrecognized setting. 110(Toolchains older than Go 1.23 reject all `godebug` lines, since they do not 111understand `godebug` at all.) 112 113The defaults from the `go` and `godebug` lines apply to all main 114packages that are built. For more fine-grained control, 115starting in Go 1.21, a main package's source files 116can include one or more `//go:debug` directives at the top of the file 117(preceding the `package` statement). 118The `godebug` lines in the previous example would be written: 119 120 //go:debug default=go1.21 121 //go:debug panicnil=1 122 //go:debug asynctimerchan=0 123 124Starting in Go 1.21, the Go toolchain treats a `//go:debug` directive 125with an unrecognized GODEBUG setting as an invalid program. 126Programs with more than one `//go:debug` line for a given setting 127are also treated as invalid. 128(Older toolchains ignore `//go:debug` directives entirely.) 129 130The defaults that will be compiled into a main package 131are reported by the command: 132 133{{raw ` 134 go list -f '{{.DefaultGODEBUG}}' my/main/package 135`}} 136 137Only differences from the base Go toolchain defaults are reported. 138 139When testing a package, `//go:debug` lines in the `*_test.go` 140files are treated as directives for the test's main package. 141In any other context, `//go:debug` lines are ignored by the toolchain; 142`go` `vet` reports such lines as misplaced. 143 144## GODEBUG History {#history} 145 146This section documents the GODEBUG settings introduced and removed in each major Go release 147for compatibility reasons. 148Packages or programs may define additional settings for internal debugging purposes; 149for example, 150see the [runtime documentation](/pkg/runtime#hdr-Environment_Variables) 151and the [go command documentation](/cmd/go#hdr-Build_and_test_caching). 152 153### Go 1.23 154 155Go 1.23 changed the channels created by package time to be unbuffered 156(synchronous), which makes correct use of the [`Timer.Stop`](/pkg/time/#Timer.Stop) 157and [`Timer.Reset`](/pkg/time/#Timer.Reset) method results much easier. 158The [`asynctimerchan` setting](/pkg/time/#NewTimer) disables this change. 159There are no runtime metrics for this change, 160This setting may be removed in a future release, Go 1.27 at the earliest. 161 162Go 1.23 changed the mode bits reported by [`os.Lstat`](/pkg/os#Lstat) and [`os.Stat`](/pkg/os#Stat) 163for reparse points, which can be controlled with the `winsymlink` setting. 164As of Go 1.23 (`winsymlink=1`), mount points no longer have [`os.ModeSymlink`](/pkg/os#ModeSymlink) 165set, and reparse points that are not symlinks, Unix sockets, or dedup files now 166always have [`os.ModeIrregular`](/pkg/os#ModeIrregular) set. As a result of these changes, 167[`filepath.EvalSymlinks`](/pkg/path/filepath#EvalSymlinks) no longer evaluates 168mount points, which was a source of many inconsistencies and bugs. 169At previous versions (`winsymlink=0`), mount points are treated as symlinks, 170and other reparse points with non-default [`os.ModeType`](/pkg/os#ModeType) bits 171(such as [`os.ModeDir`](/pkg/os#ModeDir)) do not have the `ModeIrregular` bit set. 172 173Go 1.23 changed [`os.Readlink`](/pkg/os#Readlink) and [`filepath.EvalSymlinks`](/pkg/path/filepath#EvalSymlinks) 174to avoid trying to normalize volumes to drive letters, which was not always even possible. 175This behavior is controlled by the `winreadlinkvolume` setting. 176For Go 1.23, it defaults to `winreadlinkvolume=1`. 177Previous versions default to `winreadlinkvolume=0`. 178 179Go 1.23 enabled the experimental post-quantum key exchange mechanism 180X25519Kyber768Draft00 by default. The default can be reverted using the 181[`tlskyber` setting](/pkg/crypto/tls/#Config.CurvePreferences). 182 183Go 1.23 changed the behavior of 184[crypto/x509.ParseCertificate](/pkg/crypto/x509/#ParseCertificate) to reject 185serial numbers that are negative. This change can be reverted with 186the [`x509negativeserial` setting](/pkg/crypto/x509/#ParseCertificate). 187 188Go 1.23 re-enabled support in html/template for ECMAScript 6 template literals by default. 189The [`jstmpllitinterp` setting](/pkg/html/template#hdr-Security_Model) no longer has 190any effect. 191 192Go 1.23 changed the default TLS cipher suites used by clients and servers when 193not explicitly configured, removing 3DES cipher suites. The default can be reverted 194using the [`tls3des` setting](/pkg/crypto/tls/#Config.CipherSuites). 195 196Go 1.23 changed the behavior of [`tls.X509KeyPair`](/pkg/crypto/tls#X509KeyPair) 197and [`tls.LoadX509KeyPair`](/pkg/crypto/tls#LoadX509KeyPair) to populate the 198Leaf field of the returned [`tls.Certificate`](/pkg/crypto/tls#Certificate). 199This behavior is controlled by the `x509keypairleaf` setting. For Go 1.23, it 200defaults to `x509keypairleaf=1`. Previous versions default to 201`x509keypairleaf=0`. 202 203Go 1.23 changed 204[`net/http.ServeContent`](/pkg/net/http#ServeContent), 205[`net/http.ServeFile`](/pkg/net/http#ServeFile), and 206[`net/http.ServeFS`](/pkg/net/http#ServeFS) to 207remove Cache-Control, Content-Encoding, Etag, and Last-Modified headers 208when serving an error. This behavior is controlled by 209the [`httpservecontentkeepheaders` setting](/pkg/net/http#ServeContent). 210Using `httpservecontentkeepheaders=1` restores the pre-Go 1.23 behavior. 211 212### Go 1.22 213 214Go 1.22 adds a configurable limit to control the maximum acceptable RSA key size 215that can be used in TLS handshakes, controlled by the [`tlsmaxrsasize` setting](/pkg/crypto/tls#Conn.Handshake). 216The default is tlsmaxrsasize=8192, limiting RSA to 8192-bit keys. To avoid 217denial of service attacks, this setting and default was backported to Go 2181.19.13, Go 1.20.8, and Go 1.21.1. 219 220Go 1.22 made it an error for a request or response read by a net/http 221client or server to have an empty Content-Length header. 222This behavior is controlled by the `httplaxcontentlength` setting. 223 224Go 1.22 changed the behavior of ServeMux to accept extended 225patterns and unescape both patterns and request paths by segment. 226This behavior can be controlled by the 227[`httpmuxgo121` setting](/pkg/net/http/#ServeMux). 228 229Go 1.22 added the [Alias type](/pkg/go/types#Alias) to [go/types](/pkg/go/types) 230for the explicit representation of [type aliases](/ref/spec#Type_declarations). 231Whether the type checker produces `Alias` types or not is controlled by the 232[`gotypesalias` setting](/pkg/go/types#Alias). 233For Go 1.22 it defaults to `gotypesalias=0`. 234For Go 1.23, `gotypesalias=1` will become the default. 235This setting will be removed in a future release, Go 1.27 at the earliest. 236 237Go 1.22 changed the default minimum TLS version supported by both servers 238and clients to TLS 1.2. The default can be reverted to TLS 1.0 using the 239[`tls10server` setting](/pkg/crypto/tls/#Config). 240 241Go 1.22 changed the default TLS cipher suites used by clients and servers when 242not explicitly configured, removing the cipher suites which used RSA based key 243exchange. The default can be reverted using the [`tlsrsakex` setting](/pkg/crypto/tls/#Config). 244 245Go 1.22 disabled 246[`ConnectionState.ExportKeyingMaterial`](/pkg/crypto/tls/#ConnectionState.ExportKeyingMaterial) 247when the connection supports neither TLS 1.3 nor Extended Master Secret 248(implemented in Go 1.21). It can be reenabled with the [`tlsunsafeekm` 249setting](/pkg/crypto/tls/#ConnectionState.ExportKeyingMaterial). 250 251Go 1.22 changed how the runtime interacts with transparent huge pages on Linux. 252In particular, a common default Linux kernel configuration can result in 253significant memory overheads, and Go 1.22 no longer works around this default. 254To work around this issue without adjusting kernel settings, transparent huge 255pages can be disabled for Go memory with the 256[`disablethp` setting](/pkg/runtime#hdr-Environment_Variable). 257This behavior was backported to Go 1.21.1, but the setting is only available 258starting with Go 1.21.6. 259This setting may be removed in a future release, and users impacted by this issue 260should adjust their Linux configuration according to the recommendations in the 261[GC guide](/doc/gc-guide#Linux_transparent_huge_pages), or switch to a Linux 262distribution that disables transparent huge pages altogether. 263 264Go 1.22 added contention on runtime-internal locks to the [`mutex` 265profile](/pkg/runtime/pprof#Profile). Contention on these locks is always 266reported at `runtime._LostContendedRuntimeLock`. Complete stack traces of 267runtime locks can be enabled with the [`runtimecontentionstacks` 268setting](/pkg/runtime#hdr-Environment_Variable). These stack traces have 269non-standard semantics, see setting documentation for details. 270 271Go 1.22 added a new [`crypto/x509.Certificate`](/pkg/crypto/x509/#Certificate) 272field, [`Policies`](/pkg/crypto/x509/#Certificate.Policies), which supports 273certificate policy OIDs with components larger than 31 bits. By default this 274field is only used during parsing, when it is populated with policy OIDs, but 275not used during marshaling. It can be used to marshal these larger OIDs, instead 276of the existing PolicyIdentifiers field, by using the 277[`x509usepolicies` setting.](/pkg/crypto/x509/#CreateCertificate). 278 279 280### Go 1.21 281 282Go 1.21 made it a run-time error to call `panic` with a nil interface value, 283controlled by the [`panicnil` setting](/pkg/builtin/#panic). 284 285Go 1.21 made it an error for html/template actions to appear inside of an ECMAScript 6 286template literal, controlled by the 287[`jstmpllitinterp` setting](/pkg/html/template#hdr-Security_Model). 288This behavior was backported to Go 1.19.8+ and Go 1.20.3+. 289 290Go 1.21 introduced a limit on the maximum number of MIME headers and multipart 291forms, controlled by the 292[`multipartmaxheaders` and `multipartmaxparts` settings](/pkg/mime/multipart#hdr-Limits) 293respectively. 294This behavior was backported to Go 1.19.8+ and Go 1.20.3+. 295 296Go 1.21 adds the support of Multipath TCP but it is only used if the application 297explicitly asked for it. This behavior can be controlled by the 298[`multipathtcp` setting](/pkg/net#Dialer.SetMultipathTCP). 299 300There is no plan to remove any of these settings. 301 302### Go 1.20 303 304Go 1.20 introduced support for rejecting insecure paths in tar and zip archives, 305controlled by the [`tarinsecurepath` setting](/pkg/archive/tar/#Reader.Next) 306and the [`zipinsecurepath` setting](/pkg/archive/zip/#NewReader). 307These default to `tarinsecurepath=1` and `zipinsecurepath=1`, 308preserving the behavior of earlier versions of Go. 309A future version of Go may change the defaults to 310`tarinsecurepath=0` and `zipinsecurepath=0`. 311 312Go 1.20 introduced automatic seeding of the 313[`math/rand`](/pkg/math/rand) global random number generator, 314controlled by the [`randautoseed` setting](/pkg/math/rand/#Seed). 315 316Go 1.20 introduced the concept of fallback roots for use during certificate verification, 317controlled by the [`x509usefallbackroots` setting](/pkg/crypto/x509/#SetFallbackRoots). 318 319Go 1.20 removed the preinstalled `.a` files for the standard library 320from the Go distribution. 321Installations now build and cache the standard library like 322packages in other modules. 323The [`installgoroot` setting](/cmd/go#hdr-Compile_and_install_packages_and_dependencies) 324restores the installation and use of preinstalled `.a` files. 325 326There is no plan to remove any of these settings. 327 328### Go 1.19 329 330Go 1.19 made it an error for path lookups to resolve to binaries in the current directory, 331controlled by the [`execerrdot` setting](/pkg/os/exec#hdr-Executables_in_the_current_directory). 332There is no plan to remove this setting. 333 334Go 1.19 started sending EDNS0 additional headers on DNS requests. 335This can reportedly break the DNS server provided on some routers, 336such as CenturyLink Zyxel C3000Z. 337This can be changed by the [`netedns0` setting](/pkg/net#hdr-Name_Resolution). 338This setting is available in Go 1.21.12, Go 1.22.5, Go 1.23, and later. 339There is no plan to remove this setting. 340 341### Go 1.18 342 343Go 1.18 removed support for SHA1 in most X.509 certificates, 344controlled by the [`x509sha1` setting](/pkg/crypto/x509#InsecureAlgorithmError). 345This setting will be removed in a future release, Go 1.22 at the earliest. 346 347### Go 1.10 348 349Go 1.10 changed how build caching worked and added test caching, along 350with the [`gocacheverify`, `gocachehash`, and `gocachetest` settings](/cmd/go/#hdr-Build_and_test_caching). 351There is no plan to remove these settings. 352 353### Go 1.6 354 355Go 1.6 introduced transparent support for HTTP/2, 356controlled by the [`http2client`, `http2server`, and `http2debug` settings](/pkg/net/http/#hdr-HTTP_2). 357There is no plan to remove these settings. 358 359### Go 1.5 360 361Go 1.5 introduced a pure Go DNS resolver, 362controlled by the [`netdns` setting](/pkg/net/#hdr-Name_Resolution). 363There is no plan to remove this setting. 364