Go1 Compatibility Guarantee

In Go1, the Go Compatibility Guarantee [Go 1 and the Future of Go Programs] ,was introduced, meaning that older versions of Go programs will also work correctly in newer versions that continue with Go. Of course, there are exceptions to this, such as security issues.

The full details are as follows.

We are often exposed to the following.

  • Security Issues: Security issues in the Go specification or implementation may be discovered and their resolution will require a breach of compatibility. The right to resolve these security issues will be reserved.

  • Unspecified behavior: While the Go specification attempts to specify all known behavior, unexpectedly there will be aspects that are undefined. Problems may arise in this area.

  • Specification errors: If it is necessary to resolve inconsistencies and incompleteness in the specification (spec), the right to resolve such issues will be reserved. No incompatible changes to the spec will be made, except for security issues.

  • Issues/Defects: If there are defects in the compiler, library that violate the specification, the right to fix these defects will be reserved.

  • Using import . Import: If you use import . "path", other names defined in the imported package may conflict with other names defined in the program in future versions. We do not recommend using import . , using it may cause the program to fail to compile in future versions.

  • References to unsafe libraries: imported unsafe packages may depend on internal properties of Go implementations. The right to modify them is reserved.

The Go core team has reported having 10+ years of experience with Go1 compatibility assurance, which is valuable to both Go teams and users.

Even in the past two years, the Go team and the industry have attributed Go's rapid development to the implementation of Go1 compatibility assurance.

It still looks like a good idea.

Extending Go Backward Compatibility

Background

While subjectively the Go team thought it was doing a good job, it was discovered that compatibility breaks were still being made. So Go's current head @RussCox launched "Extending Go backward compatibility".

It was thought worthwhile to extend Go1's backward compatibility to try to break programs less, to explicitly set up GODEBUG, and to make it easier to declare when change items are adapted for use and control.

In short, the Go1 compatibility promise has given Go a very large benefit, and it is important to continue to extend the advantageous items and stretch the long board.

Why did you suddenly bring up

So why the sudden desire to get into this? Because Russ Cox recently talked to the Kubernetes team and found that Go has averaged about one disruptive change to Kubernetes per year for the past few years.

He thinks Kubernetes is definitely not an isolated case. While 1 per year or so is not a high frequency, the Go team is aiming for 0 in Go1 compatibility.

Existing GODEBUG settings related to compatibility include the following.

  • GODEBUG=asyncpreemptoff=1: Disables signal-based Goroutine preemption, which occasionally finds OS errors.

  • GODEBUG=cgocheck=0: Disables runtime CGO pointer checking.

  • GODEBUG=cpu.<extension>=off: disable the use of a particular CPU extension at runtime.

  • GODEBUG=http2client=0: disable HTTP/2 for clients.

  • GODEBUG=http2server=0: Disable server-side HTTP/2.

  • GODEBUG=netdns=cgo: force the use of CGO parser.

  • GODEBUG=netdns=go: Force the use of Go DNS resolver.

Expanded Go1 Compatibility Guarantee

In the new proposal, Go will formalize and expand its use of GODEBUG by setting the corresponding GODEBUG based on the Go version number in go.mod to provide compatibility beyond that guaranteed by current compatibility guidelines.

This means that the previous GODEBUG configuration items will be extended and used more widely.

The details of the new measures are as follows.

  • Promise to always add GODEBUG settings for changes allowed by the compatibility guide, but this may still break a large number of actual programs.

  • GODEBUG settings are guaranteed to last for at least 2 years (4 versions). This is a minimum requirement; there will be, for example, http2server, which may last forever.

  • Provides runtime/metrics counters that can be used to observe non-default behaviors caused by GODEBUG settings. For example: /godebug/non-default-behavior/<name>:events.

  • Set the corresponding GODEBUG settings for the Go application based on the Go version in go.mod of the main Go modules module. Note that this is not the currently compiled version of Go. It is based on the Go version number in go.mod.

  • Allows to override a specific default GODEBUG setting in the main package source code with one or more lines of the following form: //go:debug <name>=<value>.

  • The use of companion toolchains such as go/build, go list, go version -m, etc. will be modified in parallel to ensure that GODEBUG settings can be viewed explicitly.

  • Document these commitments and how to configure the use of GODEBUG in the compatibility guide.

A more specific case is actually similar to the existing GODEBUG. For example, Go1.20 introduced a new GODEBUG zipinsecurepath.

The following process specification will be followed.

  • The default value in Go1.20 is 1 to preserve the old behavior and allow unsafe paths.

  • Go1.21 may change the default value to 0 to start rejecting unsafe paths in archive/zip. If this is the case, and Go1.21 also implements this GODEBUG proposal, then unsafe paths will continue to be allowed when using Go1.21 compiled modules with Go1.20 (go.mod). It is only when these module versions are updated to Go1.21 that they will begin to reject unsafe paths.

Summary

Go has placed increasing importance on Go1 compatibility guarantees over the years, and will be further strengthened this year. The proposal has reached the final stage and will most likely be accepted, and the latest comments have no objections.

The proposal will increase the application of GODEBUG in compatibility, and most importantly, will adjust GODEBUG according to the Go version in the go.mod file, which will be a major micro-adjustment.

The only tangled students, mainly feedback many Go developers, do not know when they modify the go.mod file go version, will lead to changes in GODEBUG, thus affecting the program, will be more obscure.

Back in the day, when rsc added the go version number to go.mod, it said it hadn't figured out where to use it... I just want to say that the tree is also buried really deep.