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