Updatify / Go lang | Release notes

Create your changelog

Go is a high-level, general-purpose programming language that is statically typed and compiled. It is known for the simplicity of its syntax and the efficiency of development that it enables through the inclusion of a large standard library supplying many needs for common projects.

Update May 7, 2026 tracked by Updatify

go1.26.3 (released 2026-05-07)

go1.26.3 (released 2026-05-07) includes security fixes to the go command, the pack tool, and the html/template, net, net/http, net/http/httputil, net/mail, and syscall packages, as well as bug fixes to the go command, the go fix command, the compiler, the linker, the runtime, and the crypto/fips140, crypto/tls, go/types, and os packages. See the Go 1.26.3 milestone on our issue tracker for details.

Update May 7, 2026 tracked by Updatify

go1.25.10 (released 2026-05-07)

go1.25.10 (released 2026-05-07) includes security fixes to the go command, the pack tool, and the html/template, net, net/http, net/http/httputil, net/mail, and syscall packages, as well as bug fixes to the go command, the compiler, the linker, the runtime, and the crypto/fips140, go/types, and os packages. See the Go 1.25.10 milestone on our issue tracker for details.

Update Apr 7, 2026 tracked by Updatify

go1.26.2 (released 2026-04-07)

go1.26.2 (released 2026-04-07) includes security fixes to the go command, the compiler, and the archive/tar, crypto/tls, crypto/x509, html/template, and os packages, as well as bug fixes to the go command, the go fix command, the compiler, the linker, the runtime, and the net, net/http, and net/url packages. See the Go 1.26.2 milestone on our issue tracker for details.

Update Feb 10, 2026 tracked by Updatify

go1.26.0 (released 2026-02-10)

Introduction to Go 1.26

The latest Go release, version 1.26, arrives in February 2026, six months after Go 1.25. Most of its changes are in the implementation of the toolchain, runtime, and libraries. As always, the release maintains the Go 1 promise of compatibility. We expect almost all Go programs to continue to compile and run as before.

Changes to the language

The built-in new function, which creates a new variable, now allows its operand to be an expression, specifying the initial value of the variable.

This feature is particularly useful when working with serialization packages such as encoding/json or protocol buffers that use a pointer to represent an optional value, as it enables an optional field to be populated in a simple expression, for example:

import "encoding/json"

type Person struct {
    Name string   `json:"name"`
    Age  *int     `json:"age"` // age if known; nil otherwise
}

func personJSON(name string, born time.Time) ([]byte, error) {
    return json.Marshal(Person{
        Name: name,
        Age:  new(yearsSince(born)),
    })
}

func yearsSince(t time.Time) int {
    return int(time.Since(t).Hours() / (365.25 * 24)) // approximately
}

The restriction that a generic type may not refer to itself in its type parameter list has been lifted. It is now possible to specify type constraints that refer to the generic type being constrained. For instance, a generic type Adder may require that it be instantiated with a type that is like itself:

type Adder[A Adder[A]] interface {
    Add(A) A
}

func algo[A Adder[A]](x, y A) A {
    return x.Add(y)
}

Previously, the self-reference to Adder on the first line was not allowed. Besides making type constraints more powerful, this change also simplifies the spec rules for type parameters ever so slightly.

Tools

Go command

The venerable go fix command has been completely revamped and is now the home of Go’s modernizers. It provides a dependable, push-button way to update Go code bases to the latest idioms and core library APIs. The initial suite of modernizers includes dozens of fixers to make use of modern features of the Go language and library, as well a source-level inliner that allows users to automate their own API migrations using //go:fix inline directives. These fixers should not change the behavior of your program, so if you encounter any issues with a fix performed by go fix, please report it.

The rewritten go fix command builds atop the exact same Go analysis framework as go vet. This means the same analyzers that provide diagnostics in go vet can be used to suggest and apply fixes in go fix. The go fix command’s historical fixers, all of which were obsolete, have been removed.

Two upcoming Go blog posts will go into more detail on modernizers, the inliner, and how to get the most out of go fix.

go mod init now defaults to a lower go version in new go.mod files. Running go mod init using a toolchain of version 1.N.X will create a go.mod file specifying the Go version go 1.(N-1).0. Pre-release versions of 1.N will create go.mod files specifying go 1.(N-2).0. For example, the Go 1.26 release candidates will create go.mod files with go 1.24.0, and Go 1.26 and its minor releases will create go.mod files with go 1.25.0. This is intended to encourage the creation of modules that are compatible with currently supported versions of Go. For additional control over the go version in new modules, go mod init can be followed up with go get go@version.

cmd/doc, and go tool doc have been deleted. go doc can be used as a replacement for go tool doc: it takes the same flags and arguments and has the same behavior.

Pprof

The pprof tool web UI, enabled with the -http flag, now defaults to the flame graph view. The previous graph view is available in the “View -> Graph” menu, or via /ui/graph.

Runtime

New garbage collector

The Green Tea garbage collector, previously available as an experiment in Go 1.25, is now enabled by default after incorporating feedback.

This garbage collector’s design improves the performance of marking and scanning small objects through better locality and CPU scalability. Benchmark results vary, but we expect somewhere between a 10–40% reduction in garbage collection overhead in real-world programs that heavily use the garbage collector. Further improvements, on the order of 10% in garbage collection overhead, are expected when running on newer amd64-based CPU platforms (Intel Ice Lake or AMD Zen 4 and newer), as the garbage collector now leverages vector instructions for scanning small objects when possible.

The new garbage collector may be disabled by setting GOEXPERIMENT=nogreenteagc at build time. This opt-out setting is expected to be removed in Go 1.27. If you disable the new garbage collector for any reason related to its performance or behavior, please file an issue.

Faster cgo calls

The baseline runtime overhead of cgo calls has been reduced by ~30%.

Heap base address randomization

On 64-bit platforms, the runtime now randomizes the heap base address at startup. This is a security enhancement that makes it harder for attackers to predict memory addresses and exploit vulnerabilities when using cgo. This feature may be disabled by setting GOEXPERIMENT=norandomizedheapbase64 at build time. This opt-out setting is expected to be removed in a future Go release.

Experimental goroutine leak profile

A new profile type that reports leaked goroutines is now available as an experiment. The new profile type, named goroutineleak in the runtime/pprof package, may be enabled by setting GOEXPERIMENT=goroutineleakprofile at build time. Enabling the experiment also makes the profile available as a net/http/pprof endpoint, /debug/pprof/goroutineleak.

A leaked goroutine is a goroutine blocked on some concurrency primitive (channels, sync.Mutex, sync.Cond, etc) that cannot possibly become unblocked. The runtime detects leaked goroutines using the garbage collector: if a goroutine G is blocked on concurrency primitive P, and P is unreachable from any runnable goroutine or any goroutine that those could unblock, then P cannot be unblocked, so goroutine G can never wake up. While it is impossible to detect permanently blocked goroutines in all cases, this approach detects a large class of such leaks.

The following example showcases a real-world goroutine leak that can be revealed by the new profile:

type result struct {
    res workResult
    err error
}

func processWorkItems(ws []workItem) ([]workResult, error) {
    // Process work items in parallel, aggregating results in ch.
    ch := make(chan result)
    for _, w := range ws {
        go func() {
            res, err := processWorkItem(w)
            ch <- result{res, err}
        }()
    }

    // Collect the results from ch, or return an error if one is found.
    var results []workResult
    for range len(ws) {
        r := <-ch
        if r.err != nil {
            // This early return may cause goroutine leaks.
            return nil, r.err
        }
        results = append(results, r.res)
    }
    return results, nil
}

Because ch is unbuffered, if processWorkItems returns early due to an error, all remaining processWorkItem goroutines will leak. Soon after this happens, ch will become unreachable to all other goroutines not involved in the leak, allowing the runtime to detect and report the leaked goroutines.

Because this technique builds on reachability, the runtime may fail to identify leaks caused by blocking on concurrency primitives reachable through global variables or the local variables of runnable goroutines.

Special thanks to Vlad Saioc at Uber for contributing this work. The underlying theory is presented in detail in a publication by Saioc et al.

The implementation is production-ready, and is only considered an experiment for the purposes of collecting feedback on the API, specifically the choice to make it a new profile. The feature is also designed to not incur any additional run-time overhead unless it is actively in-use.

We encourage users to try out the new feature in the Go playground, in tests, in continuous integration, and in production. We welcome additional feedback on the proposal issue.

We aim to enable goroutine leak profiles by default in Go 1.27.

Compiler

The compiler can now allocate the backing store for slices on the stack in more situations, which improves performance. If this change is causing trouble, the bisect tool can be used to find the allocation causing trouble using the -compile=variablemake flag. All such new stack allocations can also be turned off using -gcflags=all=-d=variablemakehash=n. If you encounter issues with this optimization, please file an issue.

Linker

On 64-bit ARM-based Windows (the windows/arm64 port), the linker now supports internal linking mode of cgo programs, which can be requested with the -ldflags=-linkmode=internal flag.

There are several minor changes to executable files. These changes do not affect running Go programs. They may affect programs that analyze Go executables, and they may affect people who use external linking mode with custom linker scripts.

  • The moduledata structure is now in its own section, named .go.module.
  • The moduledata cutab field, which is a slice, now has the correct length; previously the length was four times too large.
  • The pcHeader found at the start of the .gopclntab section no longer records the start of the text section. That field is now always zero.
  • That pcHeader change was made so that the .gopclntab section no longer contains any relocations. On platforms that support relro, the section has moved from the relro segment to the rodata segment.
  • The funcdata symbols and the findfunctab have moved from the .rodata section to the .gopclntab section.
  • The .gosymtab section has been removed. It was previously always present but empty.
  • When using internal linking, ELF sections now appear in the section header list sorted by address. The previous order was somewhat unpredictable.

The references to section names here use the ELF names as seen on Linux and other systems. The Mach-O names as seen on Darwin start with a double underscore and do not contain any dots.

Bootstrap

As mentioned in the Go 1.24 release notes, Go 1.26 now requires Go 1.24.6 or later for bootstrap. We expect that Go 1.28 will require a minor release of Go 1.26 or later for bootstrap.

Standard library

New crypto/hpke package

The new crypto/hpke package implements Hybrid Public Key Encryption (HPKE) as specified in RFC 9180, including support for post-quantum hybrid KEMs.

New experimental simd/archsimd package

Go 1.26 introduces a new experimental simd/archsimd package, which can be enabled by setting the environment variable GOEXPERIMENT=simd at build time. This package provides access to architecture-specific SIMD operations. It is currently available on the amd64 architecture and supports 128-bit, 256-bit, and 512-bit vector types, such as Int8x16 and Float64x8, with operations such as Int8x16.Add. The API is not yet considered stable.

We intend to provide support for other architectures in future versions, but the API intentionally architecture-specific and thus non-portable. In addition, we plan to develop a high-level portable SIMD package in the future.

See the package documentation and the proposal issue for more details.

New experimental runtime/secret package

The new runtime/secret package is available as an experiment, which can be enabled by setting the environment variable GOEXPERIMENT=runtimesecret at build time. It provides a facility for securely erasing temporaries used in code that manipulates secret information—typically cryptographic in nature—such as registers, stack, new heap allocations. This package is intended to make it easier to ensure forward secrecy. It currently supports the amd64 and arm64 architectures on Linux.

Minor changes to the library

bytes

The new Buffer.Peek method returns the next n bytes from the buffer without advancing it.

crypto

The new Encapsulator and Decapsulator interfaces allow accepting abstract KEM encapsulation or decapsulation keys.

crypto/dsa

The random parameter to GenerateKey is now ignored. Instead, it now always uses a secure source of cryptographically random bytes. For deterministic testing, use the new testing/cryptotest.SetGlobalRandom function. The new GODEBUG setting cryptocustomrand=1 temporarily restores the old behavior.

crypto/ecdh

The random parameter to Curve.GenerateKey is now ignored. Instead, it now always uses a secure source of cryptographically random bytes. For deterministic testing, use the new testing/cryptotest.SetGlobalRandom function. The new GODEBUG setting cryptocustomrand=1 temporarily restores the old behavior.

The new KeyExchanger interface, implemented by PrivateKey, makes it possible to accept abstract ECDH private keys, e.g. those implemented in hardware.

crypto/ecdsa

The big.Int fields of PublicKey and PrivateKey are now deprecated.

The random parameter to GenerateKey, SignASN1, Sign, and PrivateKey.Sign is now ignored. Instead, they now always use a secure source of cryptographically random bytes. For deterministic testing, use the new testing/cryptotest.SetGlobalRandom function. The new GODEBUG setting cryptocustomrand=1 temporarily restores the old behavior.

crypto/ed25519

If the random parameter to GenerateKey is nil, GenerateKey now always uses a secure source of cryptographically random bytes, instead of crypto/rand.Reader (which could have been overridden). The new GODEBUG setting cryptocustomrand=1 temporarily restores the old behavior.

crypto/fips140

FIPS 140-3 Go Cryptographic Module v1.26.0 includes changes made to the crypto/internal/fips140/... packages up to this release, and can now be selected with GOFIPS140.

The new WithoutEnforcement and Enforced functions now allow running in GODEBUG=fips140=only mode while selectively disabling the strict FIPS 140-3 checks.

Version returns the resolved FIPS 140-3 Go Cryptographic Module version when building against a frozen module with GOFIPS140.

crypto/mlkem

The new DecapsulationKey768.Encapsulator and DecapsulationKey1024.Encapsulator methods implement the new crypto.Decapsulator interface.

Encapsulation and decapsultion operations are now approximately 18% faster.

crypto/mlkem/mlkemtest

The new crypto/mlkem/mlkemtest package exposes the Encapsulate768 and Encapsulate1024 functions which implement derandomized ML-KEM encapsulation, for use with known-answer tests.

crypto/rand

The random parameter to Prime is now ignored. Instead, it now always uses a secure source of cryptographically random bytes. For deterministic testing, use the new testing/cryptotest.SetGlobalRandom function. The new GODEBUG setting cryptocustomrand=1 temporarily restores the old behavior.

crypto/rsa

The new EncryptOAEPWithOptions function allows specifying different hash functions for OAEP padding and MGF1 mask generation.

The random parameter to GenerateKey, GenerateMultiPrimeKey, and EncryptPKCS1v15 is now ignored. Instead, they now always use a secure source of cryptographically random bytes. For deterministic testing, use the new testing/cryptotest.SetGlobalRandom function. The new GODEBUG setting cryptocustomrand=1 temporarily restores the old behavior.

If PrivateKey fields are modified after calling PrivateKey.Precompute, PrivateKey.Validate now fails.

PrivateKey.D is now checked for consistency with precomputed values, even if it is not used.

Unsafe PKCS #1 v1.5 encryption padding (implemented by EncryptPKCS1v15, DecryptPKCS1v15, and DecryptPKCS1v15SessionKey) is now deprecated.

crypto/sha3

The zero value of SHA3 is now a usable SHA3-256 instance, and the zero value of SHAKE is now a usable SHAKE256 instance.

crypto/subtle

The WithDataIndependentTiming function no longer locks the calling goroutine to the OS thread while executing the passed function. Additionally, any goroutines which are spawned during the execution of the passed function and their descendants now inherit the properties of WithDataIndependentTiming for their lifetime. This change also affects cgo in the following ways:

  • Any C code called via cgo from within the function passed to WithDataIndependentTiming, or from a goroutine spawned by the function passed to WithDataIndependentTiming and its descendants, will also have data independent timing enabled for the duration of the call. If the C code disables data independent timing, it will be re-enabled on return to Go.
  • If C code called via cgo, from the function passed to WithDataIndependentTiming or elsewhere, enables or disables data independent timing then calling into Go will preserve that state for the duration of the call.

crypto/tls

The hybrid SecP256r1MLKEM768 and SecP384r1MLKEM1024 post-quantum key exchanges are now enabled by default. They can be disabled by setting Config.CurvePreferences or with the tlssecpmlkem=0 GODEBUG setting.

The new ClientHelloInfo.HelloRetryRequest field indicates if the ClientHello was sent in response to a HelloRetryRequest message. The new ConnectionState.HelloRetryRequest field indicates if the server sent a HelloRetryRequest, or if the client received a HelloRetryRequest, depending on connection role.

The QUICConn type used by QUIC implementations includes a new event for reporting TLS handshake errors.

If Certificate.PrivateKey implements crypto.MessageSigner, its SignMessage method is used instead of Sign in TLS 1.2 and later.

The following GODEBUG settings introduced in Go 1.22 and Go 1.23 will be removed in the next major Go release. Starting in Go 1.27, the new behavior will apply regardless of GODEBUG setting or go.mod language version.

  • tlsunsafeekm: ConnectionState.ExportKeyingMaterial will require TLS 1.3 or Extended Master Secret.
  • tlsrsakex: legacy RSA-only key exchanges without ECDH won’t be enabled by default.
  • tls10server: the default minimum TLS version for both clients and servers will be TLS 1.2.
  • tls3des: the default cipher suites will not include 3DES.
  • x509keypairleaf: X509KeyPair and LoadX509KeyPair will always populate the Certificate.Leaf field.

crypto/x509

The ExtKeyUsage and KeyUsage types now have String methods that return the corresponding OID names as defined in RFC 5280 and other registries.

The ExtKeyUsage type now has an OID method that returns the corresponding OID for the EKU.

The new OIDFromASN1OID function allows converting an encoding/asn1.ObjectIdentifier into an OID.

debug/elf

Additional R_LARCH_* constants from LoongArch ELF psABI v20250521 (global version v2.40) are defined for use with LoongArch systems.

errors

The new AsType function is a generic version of As. It is type-safe, faster, and, in most cases, easier to use.

fmt

For unformatted strings, fmt.Errorf("x") now allocates less and generally matches the allocations for errors.New("x").

go/ast

The new ParseDirective function parses directive comments, which are comments such as //go:generate. Source code tools can support their own directive comments and this new API should help them implement the conventional syntax.

The new BasicLit.ValueEnd field records the precise end position of a literal so that the BasicLit.End method can now always return the correct answer. (Previously it was computed using a heuristic that was incorrect for multi-line raw string literals in Windows source files, due to removal of carriage returns.)

Programs that update the ValuePos field of BasicLit s produced by the parser may need to also update or clear the ValueEnd field to avoid minor differences in formatted output.

go/token

The new File.End convenience method returns the file’s end position.

go/types

The gotypesalias GODEBUG setting introduced in Go 1.22 will be removed in the next major Go release. Starting in Go 1.27, the go/types package will always produce an Alias type for the representation of type aliases regardless of GODEBUG setting or go.mod language version.

image/jpeg

The JPEG encoder and decoder have been replaced with new, faster, more accurate implementations. Code that expects specific bit-for-bit outputs from the encoder or decoder may need to be updated.

io

ReadAll now allocates less intermediate memory and returns a minimally sized final slice. It is often about two times faster while typically allocating around half as much total memory, with more benefit for larger inputs.

log/slog

The NewMultiHandler function creates a MultiHandler that invokes all the given Handlers. Its Enabled method reports whether any of the handlers’ Enabled methods return true. Its Handle, WithAttrs and WithGroup methods call the corresponding method on each of the enabled handlers.

net

The new Dialer methods DialIP, DialTCP, DialUDP, and DialUnix permit dialing specific network types with context values.

net/http

The new HTTP2Config.StrictMaxConcurrentRequests field controls whether a new connection should be opened if an existing HTTP/2 connection has exceeded its stream limit.

The new Transport.NewClientConn method returns a client connection to an HTTP server. Most users should continue to use Transport.RoundTrip to make requests, which manages a pool of connections. NewClientConn is useful for users who need to implement their own connection management.

Client now uses and sets cookies scoped to URLs with the host portion matching Request.Host when available. Previously, the connection address host was always used. ServeMux trailing slash redirects now use HTTP status 307 (Temporary Redirect) instead of 301 (Moved Permanently).

net/http/httptest

The HTTP client returned by Server.Client will now redirect requests for example.com and any subdomains to the server being tested.

net/http/httputil

The ReverseProxy.Director configuration field is deprecated in favor of ReverseProxy.Rewrite.

A malicious client can remove headers added by a Director function by designating those headers as hop-by-hop. Since there is no way to address this problem within the scope of the Director API, we added a new Rewrite hook in Go 1.20. Rewrite hooks are provided with both the unmodified inbound request received by the proxy and the outbound request which will be sent by the proxy.

Since the Director hook is fundamentally unsafe, we are now deprecating it.

net/netip

The new Prefix.Compare method compares two prefixes.

net/url

Parse now rejects malformed URLs containing colons in the host subcomponent, such as http://::1/ or http://localhost:80:80/. URLs containing bracketed IPv6 addresses, such as http://[::1]/ are still accepted. The new GODEBUG setting urlstrictcolons=0 restores the old behavior.

os

The new Process.WithHandle method provides access to an internal process handle on supported platforms (pidfd on Linux 5.4 or later, Handle on Windows).

On Windows, the OpenFile flag parameter can now contain any combination of Windows-specific file flags, such as FILE_FLAG_OVERLAPPED and FILE_FLAG_SEQUENTIAL_SCAN, for control of file or device caching behavior, access modes, and other special-purpose flags.

os/signal

NotifyContext now cancels the returned context with context.CancelCauseFunc and an error indicating which signal was received.

reflect

The new methods Type.Fields, Type.Methods, Type.Ins and Type.Outs return iterators for a type’s fields (for a struct type), methods, inputs and outputs parameters (for a function type), respectively.

Similarly, the new methods Value.Fields and Value.Methods return iterators over a value’s fields or methods, respectively. Each iteration yields the type information ( StructField or Method) of a field or method, along with the field or method Value.

runtime/metrics

Several new scheduler metrics have been added, including counts of goroutines in various states (waiting, runnable, etc.) under the /sched/goroutines prefix, the number of OS threads the runtime is aware of with /sched/threads:threads, and the total number of goroutines created by the program with /sched/goroutines-created:goroutines.

testing

The new methods T.ArtifactDir, B.ArtifactDir, and F.ArtifactDir return a directory in which to write test output files (artifacts).

When the -artifacts flag is provided to go test, this directory will be located under the output directory (specified with -outputdir, or the current directory by default). Otherwise, artifacts are stored in a temporary directory which is removed after the test completes.

The first call to ArtifactDir when -artifacts is provided writes the location of the directory to the test log.

For example, in a test named TestArtifacts, t.ArtifactDir() emits:

=== ARTIFACTS TestArtifacts /path/to/artifact/dir

The B.Loop method no longer prevents inlining in the loop body, which could lead to unanticipated allocation and slower benchmarks. With this fix, we expect that all benchmarks can be converted from the old B.N style to the new B.Loop style with no ill effects. Within the body of a for b.Loop() { ... } loop, function call parameters, results, and assigned variables are still kept alive, preventing the compiler from optimizing away entire parts of the benchmark.

testing/cryptotest

The new SetGlobalRandom function configures a global, deterministic cryptographic randomness source for the duration of the test. It affects crypto/rand, and all implicit sources of cryptographic randomness in the crypto/... packages.

time

The asynctimerchan GODEBUG setting introduced in Go 1.23 will be removed in the next major Go release. Starting in Go 1.27, the time package will always use unbuffered (synchronous) channels for timers regardless of GODEBUG setting or go.mod language version.

Ports

Darwin

Go 1.26 is the last release that will run on macOS 12 Monterey. Go 1.27 will require macOS 13 Ventura or later.

FreeBSD

The freebsd/riscv64 port ( GOOS=freebsd GOARCH=riscv64) has been marked broken. See issue 76475 for details.

Windows

As announced in the Go 1.25 release notes, the broken 32-bit windows/arm port ( GOOS=windows GOARCH=arm) has been removed.

PowerPC

Go 1.26 is the last release that supports the ELFv1 ABI on the big-endian 64-bit PowerPC port on Linux ( GOOS=linux GOARCH=ppc64). It will switch to the ELFv2 ABI in Go 1.27. As the port does not currently support linking against other ELF objects, we expect this change to be transparent to users.

RISC-V

The linux/riscv64 port now supports the race detector.

S390X

The s390x port now supports passing function arguments and results using registers.

WebAssembly

The compiler now unconditionally makes use of the sign extension and non-trapping floating-point to integer conversion instructions. These features have been standardized since at least Wasm 2.0. The corresponding GOWASM settings, signext and satconv, are now ignored.

For WebAssembly applications, the runtime now manages chunks of heap memory in much smaller increments, leading to significantly reduced memory usage for applications with heaps less than around 16 MiB in size.

Update Oct 7, 2025 tracked by Updatify

go1.25.2 (released 2025-10-07)

go1.25.2 (released 2025-10-07) includes security fixes to the archive/tar, crypto/tls, crypto/x509, encoding/asn1, encoding/pem, net/http, net/mail, net/textproto, and net/url packages, as well as bug fixes to the compiler, the runtime, and the context, debug/pe, net/http, os, and sync/atomic packages. See the Go 1.25.2 milestone on our issue tracker for details.

Update Oct 7, 2025 tracked by Updatify

go1.24.8 (released 2025-10-07)

go1.24.8 (released 2025-10-07) includes security fixes to the archive/tar, crypto/tls, crypto/x509, encoding/asn1, encoding/pem, net/http, net/mail, net/textproto, and net/url packages, as well as bug fixes to the compiler, the linker, and the debug/pe, net/http, os, and sync/atomic packages. See the Go 1.24.8 milestone on our issue tracker for details.

Update Aug 12, 2025 tracked by Updatify

go1.25.0 (released 2025-08-12)

Introduction to Go 1.25

The latest Go release, version 1.25, arrives in August 2025, six months after Go 1.24. Most of its changes are in the implementation of the toolchain, runtime, and libraries. As always, the release maintains the Go 1 promise of compatibility. We expect almost all Go programs to continue to compile and run as before.

Changes to the language

There are no languages changes that affect Go programs in Go 1.25. However, in the language specification the notion of core types has been removed in favor of dedicated prose. See the respective blog post for more information.

Tools

Go command

The go build -asan option now defaults to doing leak detection at program exit. This will report an error if memory allocated by C is not freed and is not referenced by any other memory allocated by either C or Go. These new error reports may be disabled by setting ASAN_OPTIONS=detect_leaks=0 in the environment when running the program.

The Go distribution will include fewer prebuilt tool binaries. Core toolchain binaries such as the compiler and linker will still be included, but tools not invoked by build or test operations will be built and run by go tool as needed.

The new go.mod ignore directive can be used to specify directories the go command should ignore. Files in these directories and their subdirectories will be ignored by the go command when matching package patterns, such as all or ./..., but will still be included in module zip files.

The new go doc -http option will start a documentation server showing documentation for the requested object, and open the documentation in a browser window.

The new go version -m -json option will print the JSON encodings of the runtime/debug.BuildInfo structures embedded in the given Go binary files.

The go command now supports using a subdirectory of a repository as the path for a module root, when resolving a module path using the syntax <meta name="go-import" content="root-path vcs repo-url subdir"> to indicate that the root-path corresponds to the subdir of the repo-url with version control system vcs.

The new work package pattern matches all packages in the work (formerly called main) modules: either the single work module in module mode or the set of workspace modules in workspace mode.

When the go command updates the go line in a go.mod or go.work file, it no longer adds a toolchain line specifying the command’s current version.

Vet

The go vet command includes new analyzers:

Runtime

Container-aware GOMAXPROCS

The default behavior of the GOMAXPROCS has changed. In prior versions of Go, GOMAXPROCS defaults to the number of logical CPUs available at startup ( runtime.NumCPU). Go 1.25 introduces two changes:

  1. On Linux, the runtime considers the CPU bandwidth limit of the cgroup containing the process, if any. If the CPU bandwidth limit is lower than the number of logical CPUs available, GOMAXPROCS will default to the lower limit. In container runtime systems like Kubernetes, cgroup CPU bandwidth limits generally correspond to the “CPU limit” option. The Go runtime does not consider the “CPU requests” option.
  2. On all OSes, the runtime periodically updates GOMAXPROCS if the number of logical CPUs available or the cgroup CPU bandwidth limit change.

Both of these behaviors are automatically disabled if GOMAXPROCS is set manually via the GOMAXPROCS environment variable or a call to runtime.GOMAXPROCS. They can also be disabled explicitly with the GODEBUG settings containermaxprocs=0 and updatemaxprocs=0, respectively.

In order to support reading updated cgroup limits, the runtime will keep cached file descriptors for the cgroup files for the duration of the process lifetime.

New experimental garbage collector

A new garbage collector is now available as an experiment. This garbage collector’s design improves the performance of marking and scanning small objects through better locality and CPU scalability. Benchmark result vary, but we expect somewhere between a 10—40% reduction in garbage collection overhead in real-world programs that heavily use the garbage collector.

The new garbage collector may be enabled by setting GOEXPERIMENT=greenteagc at build time. We expect the design to continue to evolve and improve. To that end, we encourage Go developers to try it out and report back their experiences. See the GitHub issue for more details on the design and instructions for sharing feedback.

Trace flight recorder

Runtime execution traces have long provided a powerful, but expensive way to understand and debug the low-level behavior of an application. Unfortunately, because of their size and the cost of continuously writing an execution trace, they were generally impractical for debugging rare events.

The new runtime/trace.FlightRecorder API provides a lightweight way to capture a runtime execution trace by continuously recording the trace into an in-memory ring buffer. When a significant event occurs, a program can call FlightRecorder.WriteTo to snapshot the last few seconds of the trace to a file. This approach produces a much smaller trace by enabling applications to capture only the traces that matter.

The length of time and amount of data captured by a FlightRecorder may be configured within the FlightRecorderConfig.

Change to unhandled panic output

The message printed when a program exits due to an unhandled panic that was recovered and repanicked no longer repeats the text of the panic value.

Previously, a program which panicked with panic("PANIC"), recovered the panic, and then repanicked with the original value would print:

panic: PANIC [recovered]
  panic: PANIC

This program will now print:

panic: PANIC [recovered, repanicked]

VMA names on Linux

On Linux systems with kernel support for anonymous virtual memory area (VMA) names ( CONFIG_ANON_VMA_NAME), the Go runtime will annotate anonymous memory mappings with context about their purpose. e.g., [anon: Go: heap] for heap memory. This can be disabled with the GODEBUG setting decoratemappings=0.

Compiler

nil pointer bug

This release fixes a compiler bug, introduced in Go 1.21, that could incorrectly delay nil pointer checks. Programs like the following, which used to execute successfully (incorrectly), will now (correctly) panic with a nil-pointer exception:

package main

import "os"

func main() {
    f, err := os.Open("nonExistentFile")
    name := f.Name()
    if err != nil {
        return
    }
    println(name)
}

This program is incorrect because it uses the result of os.Open before checking the error. If err is non-nil, then the f result may be nil, in which case f.Name() should panic. However, in Go versions 1.21 through 1.24, the compiler incorrectly delayed the nil check until after the error check, causing the program to execute successfully, in violation of the Go spec. In Go 1.25, it will no longer run successfully. If this change is affecting your code, the solution is to put the non-nil error check earlier in your code, preferably immediately after the error-generating statement.

DWARF5 support

The compiler and linker in Go 1.25 now generate debug information using DWARF version 5. The newer DWARF version reduces the space required for debugging information in Go binaries, and reduces the time for linking, especially for large Go binaries. DWARF 5 generation can be disabled by setting the environment variable GOEXPERIMENT=nodwarf5 at build time (this fallback may be removed in a future Go release).

Faster slices

The compiler can now allocate the backing store for slices on the stack in more situations, which improves performance. This change has the potential to amplify the effects of incorrect unsafe.Pointer usage, see for example issue 73199. In order to track down these problems, the bisect tool can be used to find the allocation causing trouble using the -compile=variablemake flag. All such new stack allocations can also be turned off using -gcflags=all=-d=variablemakehash=n.

Linker

The linker now accepts a -funcalign=N command line option, which specifies the alignment of function entries. The default value is platform-dependent, and is unchanged in this release.

Standard library

New testing/synctest package

The new testing/synctest package provides support for testing concurrent code.

The Test function runs a test function in an isolated “bubble”. Within the bubble, time is virtualized: time package functions operate on a fake clock and the clock moves forward instantaneously if all goroutines in the bubble are blocked.

The Wait function waits for all goroutines in the current bubble to block.

This package was first available in Go 1.24 under GOEXPERIMENT=synctest, with a slightly different API. The experiment has now graduated to general availability. The old API is still present if GOEXPERIMENT=synctest is set, but will be removed in Go 1.26.

New experimental encoding/json/v2 package

Go 1.25 includes a new, experimental JSON implementation, which can be enabled by setting the environment variable GOEXPERIMENT=jsonv2 at build time.

When enabled, two new packages are available:

In addition, when the “jsonv2” GOEXPERIMENT is enabled:

  • The encoding/json package uses the new JSON implementation. Marshaling and unmarshaling behavior is unaffected, but the text of errors returned by package function may change.
  • The encoding/json package contains a number of new options which may be used to configure the marshaler and unmarshaler.

The new implementation performs substantially better than the existing one under many scenarios. In general, encoding performance is at parity between the implementations and decoding is substantially faster in the new one. See the github.com/go-json-experiment/jsonbench repository for more detailed analysis.

See the proposal issue for more details.

We encourage users of encoding/json to test their programs with GOEXPERIMENT=jsonv2 enabled to help detect any compatibility issues with the new implementation.

We expect the design of encoding/json/v2 to continue to evolve. We encourage developers to try out the new API and provide feedback on the proposal issue.

Minor changes to the library

archive/tar

The Writer.AddFS implementation now supports symbolic links for filesystems that implement io/fs.ReadLinkFS.

encoding/asn1

Unmarshal and UnmarshalWithParams now parse the ASN.1 types T61String and BMPString more consistently. This may result in some previously accepted malformed encodings now being rejected.

crypto

MessageSigner is a new signing interface that can be implemented by signers that wish to hash the message to be signed themselves. A new function is also introduced, SignMessage, which attempts to upgrade a Signer interface to MessageSigner, using the MessageSigner.SignMessage method if successful, and Signer.Sign if not. This can be used when code wishes to support both Signer and MessageSigner.

Changing the fips140 GODEBUG setting after the program has started is now a no-op. Previously, it was documented as not allowed, and could cause a panic if changed.

SHA-1, SHA-256, and SHA-512 are now slower on amd64 when AVX2 instructions are not available. All server processors (and most others) produced since 2015 support AVX2.

crypto/ecdsa

The new ParseRawPrivateKey, ParseUncompressedPublicKey, PrivateKey.Bytes, and PublicKey.Bytes functions and methods implement low-level encodings, replacing the need to use crypto/elliptic or math/big functions and methods.

When FIPS 140-3 mode is enabled, signing is now four times faster, matching the performance of non-FIPS mode.

crypto/ed25519

When FIPS 140-3 mode is enabled, signing is now four times faster, matching the performance of non-FIPS mode.

crypto/elliptic

The hidden and undocumented Inverse and CombinedMult methods on some Curve implementations have been removed.

crypto/rsa

PublicKey no longer claims that the modulus value is treated as secret. VerifyPKCS1v15 and VerifyPSS already warned that all inputs are public and could be leaked, and there are mathematical attacks that can recover the modulus from other public values.

Key generation is now three times faster.

crypto/sha1

Hashing is now two times faster on amd64 when SHA-NI instructions are available.

crypto/sha3

The new SHA3.Clone method implements hash.Cloner.

Hashing is now two times faster on Apple M processors.

crypto/tls

The new ConnectionState.CurveID field exposes the key exchange mechanism used to establish the connection.

The new Config.GetEncryptedClientHelloKeys callback can be used to set the EncryptedClientHelloKey s for a server to use when a client sends an Encrypted Client Hello extension.

SHA-1 signature algorithms are now disallowed in TLS 1.2 handshakes, per RFC 9155. They can be re-enabled with the GODEBUG setting tlssha1=1.

When FIPS 140-3 mode is enabled, Extended Master Secret is now required in TLS 1.2, and Ed25519 and X25519MLKEM768 are now allowed.

TLS servers now prefer the highest supported protocol version, even if it isn’t the client’s most preferred protocol version.

Both TLS clients and servers are now stricter in following the specifications and in rejecting off-spec behavior. Connections with compliant peers should be unaffected.

crypto/x509

CreateCertificate, CreateCertificateRequest, and CreateRevocationList can now accept a crypto.MessageSigner signing interface as well as crypto.Signer. This allows these functions to use signers which implement “one-shot” signing interfaces, where hashing is done as part of the signing operation, instead of by the caller.

CreateCertificate now uses truncated SHA-256 to populate the SubjectKeyId if it is missing. The GODEBUG setting x509sha256skid=0 reverts to SHA-1.

ParseCertificate now rejects certificates which contain a BasicConstraints extension that contains a negative pathLenConstraint.

ParseCertificate now handles strings encoded with the ASN.1 T61String and BMPString types more consistently. This may result in some previously accepted malformed encodings now being rejected.

debug/elf

The debug/elf package adds two new constants:

go/ast

The FilterPackage, PackageExports, and MergePackageFiles functions, and the MergeMode type and its constants, are all deprecated, as they are for use only with the long-deprecated Object and Package machinery.

The new PreorderStack function, like Inspect, traverses a syntax tree and provides control over descent into subtrees, but as a convenience it also provides the stack of enclosing nodes at each point.

go/parser

The ParseDir function is deprecated.

go/token

The new FileSet.AddExistingFiles method enables existing File s to be added to a FileSet, or a FileSet to be constructed for an arbitrary set of File s, alleviating the problems associated with a single global FileSet in long-lived applications.

go/types

Var now has a Var.Kind method that classifies the variable as one of: package-level, receiver, parameter, result, local variable, or a struct field.

The new LookupSelection function looks up the field or method of a given name and receiver type, like the existing LookupFieldOrMethod function, but returns the result in the form of a Selection.

hash

The new XOF interface can be implemented by “extendable output functions”, which are hash functions with arbitrary or unlimited output length such as SHAKE.

Hashes implementing the new Cloner interface can return a copy of their state. All standard library Hash implementations now implement Cloner.

hash/maphash

The new Hash.Clone method implements hash.Cloner.

io/fs

A new ReadLinkFS interface provides the ability to read symbolic links in a filesystem.

log/slog

GroupAttrs creates a group Attr from a slice of Attr values.

Record now has a Source method, returning its source location or nil if unavailable.

mime/multipart

The new helper function FileContentDisposition builds multipart Content-Disposition header fields.

net

LookupMX and Resolver.LookupMX now return DNS names that look like valid IP address, as well as valid domain names. Previously if a name server returned an IP address as a DNS name, LookupMX would discard it, as required by the RFCs. However, name servers in practice do sometimes return IP addresses.

On Windows, ListenMulticastUDP now supports IPv6 addresses.

On Windows, it is now possible to convert between an os.File and a network connection. Specifically, the FileConn, FilePacketConn, and FileListener functions are now implemented, and return a network connection or listener corresponding to an open file. Similarly, the File methods of TCPConn, UDPConn, UnixConn, IPConn, TCPListener, and UnixListener are now implemented, and return the underlying os.File of a network connection.

net/http

The new CrossOriginProtection implements protections against Cross-Site Request Forgery (CSRF) by rejecting non-safe cross-origin browser requests. It uses modern browser Fetch metadata, doesn’t require tokens or cookies, and supports origin-based and pattern-based bypasses.

os

On Windows, NewFile now supports handles opened for asynchronous I/O (that is, syscall.FILE_FLAG_OVERLAPPED is specified in the syscall.CreateFile call). These handles are associated with the Go runtime’s I/O completion port, which provides the following benefits for the resulting File:

This enhancement is especially beneficial for applications that communicate via named pipes on Windows.

Note that a handle can only be associated with one completion port at a time. If the handle provided to NewFile is already associated with a completion port, the returned File is downgraded to synchronous I/O mode. In this case, I/O methods will block an OS thread, and the deadline methods have no effect.

The filesystems returned by DirFS and Root.FS implement the new io/fs.ReadLinkFS interface. CopyFS supports symlinks when copying filesystems that implement io/fs.ReadLinkFS.

The Root type supports the following additional methods:

reflect

The new TypeAssert function permits converting a Value directly to a Go value of the given type. This is like using a type assertion on the result of Value.Interface, but avoids unnecessary memory allocations.

regexp/syntax

The \p{name} and \P{name} character class syntaxes now accept the names Any, ASCII, Assigned, Cn, and LC, as well as Unicode category aliases like \p{Letter} for \pL. Following Unicode TR18, they also now use case-insensitive name lookups, ignoring spaces, underscores, and hyphens.

runtime

Cleanup functions scheduled by AddCleanup are now executed concurrently and in parallel, making cleanups more viable for heavy use like the unique package. Note that individual cleanups should still shunt their work to a new goroutine if they must execute or block for a long time to avoid blocking the cleanup queue.

A new GODEBUG=checkfinalizers=1 setting helps find common issues with finalizers and cleanups, such as those described in the GC guide. In this mode, the runtime runs diagnostics on each garbage collection cycle, and will also regularly report the finalizer and cleanup queue lengths to stderr to help identify issues with long-running finalizers and/or cleanups. See the GODEBUG documentation for more details.

The new SetDefaultGOMAXPROCS function sets GOMAXPROCS to the runtime default value, as if the GOMAXPROCS environment variable is not set. This is useful for enabling the new GOMAXPROCS default if it has been disabled by the GOMAXPROCS environment variable or a prior call to GOMAXPROCS.

runtime/pprof

The mutex profile for contention on runtime-internal locks now correctly points to the end of the critical section that caused the delay. This matches the profile’s behavior for contention on sync.Mutex values. The runtimecontentionstacks setting for GODEBUG, which allowed opting in to the unusual behavior of Go 1.22 through 1.24 for this part of the profile, is now gone.

sync

The new WaitGroup.Go method makes the common pattern of creating and counting goroutines more convenient.

testing

The new methods T.Attr, B.Attr, and F.Attr emit an attribute to the test log. An attribute is an arbitrary key and value associated with a test.

For example, in a test named TestF, t.Attr("key", "value") emits:

=== ATTR  TestF key value

With the -json flag, attributes appear as a new “attr” action.

The new Output method of T, B and F provides an io.Writer that writes to the same test output stream as TB.Log. Like TB.Log, the output is indented, but it does not include the file and line number.

The AllocsPerRun function now panics if parallel tests are running. The result of AllocsPerRun is inherently flaky if other tests are running. The new panicking behavior helps catch such bugs.

testing/fstest

MapFS implements the new io/fs.ReadLinkFS interface. TestFS will verify the functionality of the io/fs.ReadLinkFS interface if implemented. TestFS will no longer follow symlinks to avoid unbounded recursion.

unicode

The new CategoryAliases map provides access to category alias names, such as “Letter” for “L”.

The new categories Cn and LC define unassigned codepoints and cased letters, respectively. These have always been defined by Unicode but were inadvertently omitted in earlier versions of Go. The C category now includes Cn, meaning it has added all unassigned code points.

unique

The unique package now reclaims interned values more eagerly, more efficiently, and in parallel. As a consequence, applications using Make are now less likely to experience memory blow-up when lots of truly unique values are interned.

Values passed to Make containing Handle s previously required multiple garbage collection cycles to collect, proportional to the depth of the chain of Handle values. Now, once unused, they are collected promptly in a single cycle.

Ports

Darwin

As announced in the Go 1.24 release notes, Go 1.25 requires macOS 12 Monterey or later. Support for previous versions has been discontinued.

Windows

Go 1.25 is the last release that contains the broken 32-bit windows/arm port ( GOOS=windows GOARCH=arm). It will be removed in Go 1.26.

AMD64

In GOAMD64=v3 mode or higher, the compiler will now use fused multiply-add instructions to make floating-point arithmetic faster and more accurate. This may change the exact floating-point values that a program generates.

To avoid fusing use an explicit float64 cast, like float64(a*b)+c.

Loong64

The linux/loong64 port now supports the race detector, gathering traceback information from C code using runtime.SetCgoTraceback, and linking cgo programs with the internal link mode.

RISC-V

The linux/riscv64 port now supports the plugin build mode.

The GORISCV64 environment variable now accepts a new value rva23u64, which selects the RVA23U64 user-mode application profile.

Update Feb 11, 2025 tracked by Updatify

go1.24.0 (released 2025-02-11)

Introduction to Go 1.24

The latest Go release, version 1.24, arrives in February 2025, six months after Go 1.23. Most of its changes are in the implementation of the toolchain, runtime, and libraries. As always, the release maintains the Go 1 promise of compatibility. We expect almost all Go programs to continue to compile and run as before.

Changes to the language

Go 1.24 now fully supports generic type aliases: a type alias may be parameterized like a defined type. See the language spec for details. For now, the feature can be disabled by setting GOEXPERIMENT=noaliastypeparams; but the aliastypeparams setting will be removed for Go 1.25.

Tools

Go command

Go modules can now track executable dependencies using tool directives in go.mod. This removes the need for the previous workaround of adding tools as blank imports to a file conventionally named “tools.go”. The go tool command can now run these tools in addition to tools shipped with the Go distribution. For more information see the documentation.

The new -tool flag for go get causes a tool directive to be added to the current module for named packages in addition to adding require directives.

The new tool meta-pattern refers to all tools in the current module. This can be used to upgrade them all with go get tool or to install them into your GOBIN directory with go install tool.

Executables created by go run and the new behavior of go tool are now cached in the Go build cache. This makes repeated executions faster at the expense of making the cache larger. See #69290.

The go build and go install commands now accept a -json flag that reports build output and failures as structured JSON output on standard output. For details of the reporting format, see go help buildjson.

Furthermore, go test -json now reports build output and failures in JSON, interleaved with test result JSON. These are distinguished by new Action types, but if they cause problems in a test integration system, you can revert to the text build output with GODEBUG setting gotestjsonbuildtext=1.

The new GOAUTH environment variable provides a flexible way to authenticate private module fetches. See go help goauth for more information.

The go build command now sets the main module’s version in the compiled binary based on the version control system tag and/or commit. A +dirty suffix will be appended if there are uncommitted changes. Use the -buildvcs=false flag to omit version control information from the binary.

The new GODEBUG setting toolchaintrace=1 can be used to trace the go command’s toolchain selection process.

Cgo

Cgo supports new annotations for C functions to improve run time performance. #cgo noescape cFunctionName tells the compiler that memory passed to the C function cFunctionname does not escape. #cgo nocallback cFunctionName tells the compiler that the C function cFunctionName does not call back to any Go functions. For more information, see the cgo documentation.

Cgo currently refuses to compile calls to a C function which has multiple incompatible declarations. For instance, if f is declared as both void f(int) and void f(double), cgo will report an error instead of possibly generating an incorrect call sequence for f(0). New in this release is a better detector for this error condition when the incompatible declarations appear in different files. See #67699.

Objdump

The objdump tool now supports dissassembly on 64-bit LoongArch ( GOARCH=loong64), RISC-V ( GOARCH=riscv64), and S390X ( GOARCH=s390x).

Vet

The new tests analyzer reports common mistakes in declarations of tests, fuzzers, benchmarks, and examples in test packages, such as malformed names, incorrect signatures, or examples that document non-existent identifiers. Some of these mistakes may cause tests not to run. This analyzer is among the subset of analyzers that are run by go test.

The existing printf analyzer now reports a diagnostic for calls of the form fmt.Printf(s), where s is a non-constant format string, with no other arguments. Such calls are nearly always a mistake as the value of s may contain the % symbol; use fmt.Print instead. See #60529. This check tends to produce findings in existing code, and so is only applied when the language version (as specified by the go.mod go directive or //go:build comments) is at least Go 1.24, to avoid causing continuous integration failures when updating to the 1.24 Go toolchain.

The existing buildtag analyzer now reports a diagnostic when there is an invalid Go major version build constraint within a //go:build directive. For example, //go:build go1.23.1 refers to a point release; use //go:build go1.23 instead. See #64127.

The existing copylock analyzer now reports a diagnostic when a variable declared in a 3-clause “for” loop such as for i := iter(); done(i); i = next(i) { ... } contains a sync.Locker, such as a sync.Mutex. Go 1.22 changed the behavior of these loops to create a new variable for each iteration, copying the value from the previous iteration; this copy operation is not safe for locks. See #66387.

GOCACHEPROG

The cmd/go internal binary and test caching mechanism can now be implemented by child processes implementing a JSON protocol between the cmd/go tool and the child process named by the GOCACHEPROG environment variable. This was previously behind a GOEXPERIMENT. For protocol details, see the documentation.

Runtime

Several performance improvements to the runtime have decreased CPU overheads by 2–3% on average across a suite of representative benchmarks. Results may vary by application. These improvements include a new builtin map implementation based on Swiss Tables, more efficient memory allocation of small objects, and a new runtime-internal mutex implementation.

The new builtin map implementation and new runtime-internal mutex may be disabled by setting GOEXPERIMENT=noswissmap and GOEXPERIMENT=nospinbitmutex at build time respectively.

Compiler

The compiler already disallowed defining new methods with receiver types that were cgo-generated, but it was possible to circumvent that restriction via an alias type. Go 1.24 now always reports an error if a receiver denotes a cgo-generated type, whether directly or indirectly (through an alias type).

Linker

The linker now generates a GNU build ID (the ELF NT_GNU_BUILD_ID note) on ELF platforms and a UUID (the Mach-O LC_UUID load command) on macOS by default. The build ID or UUID is derived from the Go build ID. It can be disabled by the -B none linker flag, or overridden by the -B 0xNNNN linker flag with a user-specified hexadecimal value.

Bootstrap

As mentioned in the Go 1.22 release notes, Go 1.24 now requires Go 1.22.6 or later for bootstrap. We expect that Go 1.26 will require a point release of Go 1.24 or later for bootstrap.

Standard library

Directory-limited filesystem access

The new os.Root type provides the ability to perform filesystem operations within a specific directory.

The os.OpenRoot function opens a directory and returns an os.Root. Methods on os.Root operate within the directory and do not permit paths that refer to locations outside the directory, including ones that follow symbolic links out of the directory. The methods on os.Root mirror most of the file system operations available in the os package, including for example os.Root.Open, os.Root.Create, os.Root.Mkdir, and os.Root.Stat,

New benchmark function

Benchmarks may now use the faster and less error-prone testing.B.Loop method to perform benchmark iterations like for b.Loop() { ... } in place of the typical loop structures involving b.N like for range b.N. This offers two significant advantages:

  • The benchmark function will execute exactly once per -count, so expensive setup and cleanup steps execute only once.
  • Function call parameters and results are kept alive, preventing the compiler from fully optimizing away the loop body.

Improved finalizers

The new runtime.AddCleanup function is a finalization mechanism that is more flexible, more efficient, and less error-prone than runtime.SetFinalizer. AddCleanup attaches a cleanup function to an object that will run once the object is no longer reachable. However, unlike SetFinalizer, multiple cleanups may be attached to a single object, cleanups may be attached to interior pointers, cleanups do not generally cause leaks when objects form a cycle, and cleanups do not delay the freeing of an object or objects it points to. New code should prefer AddCleanup over SetFinalizer.

New weak package

The new weak package provides weak pointers.

Weak pointers are a low-level primitive provided to enable the creation of memory-efficient structures, such as weak maps for associating values, canonicalization maps for anything not covered by package unique, and various kinds of caches. For supporting these use-cases, this release also provides runtime.AddCleanup and maphash.Comparable.

New crypto/mlkem package

The new crypto/mlkem package implements ML-KEM-768 and ML-KEM-1024.

ML-KEM is a post-quantum key exchange mechanism formerly known as Kyber and specified in FIPS 203.

New crypto/hkdf, crypto/pbkdf2, and crypto/sha3 packages

The new crypto/hkdf package implements the HMAC-based Extract-and-Expand key derivation function HKDF, as defined in RFC 5869.

The new crypto/pbkdf2 package implements the password-based key derivation function PBKDF2, as defined in RFC 8018.

The new crypto/sha3 package implements the SHA-3 hash function and SHAKE and cSHAKE extendable-output functions, as defined in FIPS 202.

All three packages are based on pre-existing golang.org/x/crypto/... packages.

FIPS 140-3 compliance

This release includes a new set of mechanisms to facilitate FIPS 140-3 compliance.

The Go Cryptographic Module is a set of internal standard library packages that are transparently used to implement FIPS 140-3 approved algorithms. Applications require no changes to use the Go Cryptographic Module for approved algorithms.

The new GOFIPS140 environment variable can be used to select the Go Cryptographic Module version to use in a build. The new fips140 GODEBUG setting can be used to enable FIPS 140-3 mode at runtime.

Go 1.24 includes Go Cryptographic Module version v1.0.0, which is currently under test with a CMVP-accredited laboratory.

New experimental testing/synctest package

The new experimental testing/synctest package provides support for testing concurrent code.

  • The synctest.Run function starts a group of goroutines in an isolated “bubble”. Within the bubble, time package functions operate on a fake clock.
  • The synctest.Wait function waits for all goroutines in the current bubble to block.

See the package documentation for more details.

The synctest package is experimental and must be enabled by setting GOEXPERIMENT=synctest at build time. The package API is subject to change in future releases. See issue #67434 for more information and to provide feeback.

Minor changes to the library

archive

The (*Writer).AddFS implementations in both archive/zip and archive/tar now write a directory header for an empty directory.

bytes

The bytes package adds several functions that work with iterators:

  • Lines returns an iterator over the newline-terminated lines in a byte slice.
  • SplitSeq returns an iterator over all subslices of a byte slice split around a separator.
  • SplitAfterSeq returns an iterator over subslices of a byte slice split after each instance of a separator.
  • FieldsSeq returns an iterator over subslices of a byte slice split around runs of whitespace characters, as defined by unicode.IsSpace.
  • FieldsFuncSeq returns an iterator over subslices of a byte slice split around runs of Unicode code points satisfying a predicate.

crypto/aes

The value returned by NewCipher no longer implements the NewCTR, NewGCM, NewCBCEncrypter, and NewCBCDecrypter methods. These methods were undocumented and not available on all architectures. Instead, the Block value should be passed directly to the relevant crypto/cipher functions. For now, crypto/cipher still checks for those methods on Block values, even if they are not used by the standard library anymore.

crypto/cipher

The new NewGCMWithRandomNonce function returns an AEAD that implements AES-GCM by generating a random nonce during Seal and prepending it to the ciphertext.

The Stream implementation returned by NewCTR when used with crypto/aes is now several times faster on amd64 and arm64.

NewOFB, NewCFBEncrypter, and NewCFBDecrypter are now deprecated. OFB and CFB mode are not authenticated, which generally enables active attacks to manipulate and recover the plaintext. It is recommended that applications use AEAD modes instead. If an unauthenticated Stream mode is required, use NewCTR instead.

crypto/ecdsa

PrivateKey.Sign now produces a deterministic signature according to RFC 6979 if the random source is nil.

crypto/md5

The value returned by md5.New now also implements the encoding.BinaryAppender interface.

crypto/rand

The Read function is now guaranteed not to fail. It will always return nil as the error result. If Read were to encounter an error while reading from Reader, the program will irrecoverably crash. Note that the platform APIs used by the default Reader are documented to always succeed, so this change should only affect programs that override the Reader variable. One exception are Linux kernels before version 3.17, where the default Reader still opens /dev/urandom and may fail.

On Linux 6.11 and later, Reader now uses the getrandom system call via vDSO. This is several times faster, especially for small reads.

On OpenBSD, Reader now uses arc4random_buf(3).

The new Text function can be used to generate cryptographically secure random text strings.

crypto/rsa

GenerateKey now returns an error if a key of less than 1024 bits is requested. All Sign, Verify, Encrypt, and Decrypt methods now return an error if used with a key smaller than 1024 bits. Such keys are insecure and should not be used. GODEBUG setting rsa1024min=0 restores the old behavior, but we recommend doing so only if necessary and only in tests, for example by adding a //go:debug rsa1024min=0 line to a test file. A new GenerateKey example provides an easy-to-use standard 2048-bit test key.

It is now safe and more efficient to call PrivateKey.Precompute before PrivateKey.Validate. Precompute is now faster in the presence of partially filled out PrecomputedValues, such as when unmarshaling a key from JSON.

The package now rejects more invalid keys, even when Validate is not called, and GenerateKey may return new errors for broken random sources. The Primes and Precomputed fields of PrivateKey are now used and validated even when some values are missing. See also the changes to crypto/x509 parsing and marshaling of RSA keys described below.

SignPKCS1v15 and VerifyPKCS1v15 now support SHA-512/224, SHA-512/256, and SHA-3.

GenerateKey now uses a slightly different method to generate the private exponent (Carmichael’s totient instead of Euler’s totient). Rare applications that externally regenerate keys from only the prime factors may produce different but compatible results.

Public and private key operations are now up to two times faster on wasm.

crypto/sha1

The value returned by sha1.New now also implements the encoding.BinaryAppender interface.

crypto/sha256

The values returned by sha256.New and sha256.New224 now also implement the encoding.BinaryAppender interface.

crypto/sha512

The values returned by sha512.New, sha512.New384, sha512.New512_224 and sha512.New512_256 now also implement the encoding.BinaryAppender interface.

crypto/subtle

The new WithDataIndependentTiming function allows the user to run a function with architecture specific features enabled which guarantee specific instructions are data value timing invariant. This can be used to make sure that code designed to run in constant time is not optimized by CPU-level features such that it operates in variable time. Currently, WithDataIndependentTiming uses the PSTATE.DIT bit on arm64, and is a no-op on all other architectures. GODEBUG setting dataindependenttiming=1 enables the DIT mode for the entire Go program.

The XORBytes output must overlap exactly or not at all with the inputs. Previously, the behavior was otherwise undefined, while now XORBytes will panic.

crypto/tls

The TLS server now supports Encrypted Client Hello (ECH). This feature can be enabled by populating the Config.EncryptedClientHelloKeys field.

The new post-quantum X25519MLKEM768 key exchange mechanism is now supported and is enabled by default when Config.CurvePreferences is nil. GODEBUG setting tlsmlkem=0 reverts the default. This can be useful when dealing with buggy TLS servers that do not handle large records correctly, causing a timeout during the handshake (see TLS post-quantum TL;DR fail).

Support for the experimental X25519Kyber768Draft00 key exchange has been removed.

Key exchange ordering is now handled entirely by the crypto/tls package. The order of Config.CurvePreferences is now ignored, and the contents are only used to determine which key exchanges to enable when the field is populated.

The new ClientHelloInfo.Extensions field lists the IDs of the extensions received in the Client Hello message. This can be useful for fingerprinting TLS clients.

crypto/x509

The x509sha1 GODEBUG setting has been removed. Certificate.Verify no longer supports SHA-1 based signatures.

OID now implements the encoding.BinaryAppender and encoding.TextAppender interfaces.

The default certificate policies field has changed from Certificate.PolicyIdentifiers to Certificate.Policies. When parsing certificates, both fields will be populated, but when creating certificates policies will now be taken from the Certificate.Policies field instead of the Certificate.PolicyIdentifiers field. This change can be reverted with GODEBUG setting x509usepolicies=0.

CreateCertificate will now generate a serial number using a RFC 5280 compliant method when passed a template with a nil Certificate.SerialNumber field, instead of failing.

Certificate.Verify now supports policy validation, as defined in RFC 5280 and RFC 9618. The new VerifyOptions.CertificatePolicies field can be set to an acceptable set of policy OIDs. Only certificate chains with valid policy graphs will be returned from Certificate.Verify.

MarshalPKCS8PrivateKey now returns an error instead of marshaling an invalid RSA key. ( MarshalPKCS1PrivateKey doesn’t have an error return, and its behavior when provided invalid keys continues to be undefined.)

ParsePKCS1PrivateKey and ParsePKCS8PrivateKey now use and validate the encoded CRT values, so might reject invalid RSA keys that were previously accepted. Use GODEBUG setting x509rsacrt=0 to revert to recomputing the CRT values.

debug/elf

The debug/elf package adds support for handling symbol versions in dynamic ELF (Executable and Linkable Format) files. The new File.DynamicVersions method returns a list of dynamic versions defined in the ELF file. The new File.DynamicVersionNeeds method returns a list of dynamic versions required by this ELF file that are defined in other ELF objects. Finally, the new Symbol.HasVersion and Symbol.VersionIndex fields indicate the version of a symbol.

encoding

Two new interfaces, TextAppender and BinaryAppender, have been introduced to append the textual or binary representation of an object to a byte slice. These interfaces provide the same functionality as TextMarshaler and BinaryMarshaler, but instead of allocating a new slice each time, they append the data directly to an existing slice. These interfaces are now implemented by standard library types that already implemented TextMarshaler and/or BinaryMarshaler.

encoding/json

When marshaling, a struct field with the new omitzero option in the struct field tag will be omitted if its value is zero. If the field type has an IsZero() bool method, that will be used to determine whether the value is zero. Otherwise, the value is zero if it is the zero value for its type. The omitzero field tag is clearer and less error-prone than omitempty when the intent is to omit zero values. In particular, unlike omitempty, omitzero omits zero-valued time.Time values, which is a common source of friction.

If both omitempty and omitzero are specified, the field will be omitted if the value is either empty or zero (or both).

UnmarshalTypeError.Field now includes embedded structs to provide more detailed error messages.

go/types

All go/types data structures that expose sequences using a pair of methods such as Len() int and At(int) T now also have methods that return iterators, allowing you to simplify code such as this:

params := fn.Type.(*types.Signature).Params()
for i := 0; i < params.Len(); i++ {
   use(params.At(i))
}

to this:

for param := range fn.Signature().Params().Variables() {
   use(param)
}

The methods are: Interface.EmbeddedTypes, Interface.ExplicitMethods, Interface.Methods, MethodSet.Methods, Named.Methods, Scope.Children, Struct.Fields, Tuple.Variables, TypeList.Types, TypeParamList.TypeParams, Union.Terms.

hash/adler32

The value returned by New now also implements the encoding.BinaryAppender interface.

hash/crc32

The values returned by New and NewIEEE now also implement the encoding.BinaryAppender interface.

hash/crc64

The value returned by New now also implements the encoding.BinaryAppender interface.

hash/fnv

The values returned by New32, New32a, New64, New64a, New128 and New128a now also implement the encoding.BinaryAppender interface.

hash/maphash

The new Comparable and WriteComparable functions can compute the hash of any comparable value. These make it possible to hash anything that can be used as a Go map key.

log/slog

The new DiscardHandler is a handler that is never enabled and always discards its output.

Level and LevelVar now implement the encoding.TextAppender interface.

math/big

Float, Int and Rat now implement the encoding.TextAppender interface.

math/rand

Calls to the deprecated top-level Seed function no longer have any effect. To restore the old behavior use GODEBUG setting randseednop=0. For more background see proposal #67273.

math/rand/v2

ChaCha8 and PCG now implement the encoding.BinaryAppender interface.

net

ListenConfig now uses MPTCP by default on systems where it is supported (currently on Linux only).

IP now implements the encoding.TextAppender interface.

net/http

Transport ’s limit on 1xx informational responses received in response to a request has changed. It previously aborted a request and returned an error after receiving more than 5 1xx responses. It now returns an error if the total size of all 1xx responses exceeds the Transport.MaxResponseHeaderBytes configuration setting.

In addition, when a request has a net/http/httptrace.ClientTrace.Got1xxResponse trace hook, there is now no limit on the total number of 1xx responses. The Got1xxResponse hook may return an error to abort a request.

Transport and Server now have an HTTP2 field which permits configuring HTTP/2 protocol settings.

The new Server.Protocols and Transport.Protocols fields provide a simple way to configure what HTTP protocols a server or client use.

The server and client may be configured to support unencrypted HTTP/2 connections.

When Server.Protocols contains UnencryptedHTTP2, the server will accept HTTP/2 connections on unencrypted ports. The server can accept both HTTP/1 and unencrypted HTTP/2 on the same port.

When Transport.Protocols contains UnencryptedHTTP2 and does not contain HTTP1, the transport will use unencrypted HTTP/2 for http:// URLs. If the transport is configured to use both HTTP/1 and unencrypted HTTP/2, it will use HTTP/1.

Unencrypted HTTP/2 support uses “HTTP/2 with Prior Knowledge” (RFC 9113, section 3.3). The deprecated “Upgrade: h2c” header is not supported.

net/netip

Addr, AddrPort and Prefix now implement the encoding.BinaryAppender and encoding.TextAppender interfaces.

net/url

URL now also implements the encoding.BinaryAppender interface.

os/user

On Windows, Current can now be used in Windows Nano Server. The implementation has been updated to avoid using functions from the NetApi32 library, which is not available in Nano Server.

On Windows, Current, Lookup and LookupId now support the following built-in service user accounts:

  • NT AUTHORITY\SYSTEM
  • NT AUTHORITY\LOCAL SERVICE
  • NT AUTHORITY\NETWORK SERVICE

On Windows, Current has been made considerably faster when the current user is joined to a slow domain, which is the usual case for many corporate users. The new implementation performance is now in the order of milliseconds, compared to the previous implementation which could take several seconds, or even minutes, to complete.

On Windows, Current now returns the process owner user when the current thread is impersonating another user. Previously, it returned an error.

regexp

Regexp now implements the encoding.TextAppender interface.

runtime

The GOROOT function is now deprecated. In new code prefer to use the system path to locate the “go” binary, and use go env GOROOT to find its GOROOT.

strings

The strings package adds several functions that work with iterators:

  • Lines returns an iterator over the newline-terminated lines in a string.
  • SplitSeq returns an iterator over all substrings of a string split around a separator.
  • SplitAfterSeq returns an iterator over substrings of a string split after each instance of a separator.
  • FieldsSeq returns an iterator over substrings of a string split around runs of whitespace characters, as defined by unicode.IsSpace.
  • FieldsFuncSeq returns an iterator over substrings of a string split around runs of Unicode code points satisfying a predicate.

sync

The implementation of sync.Map has been changed, improving performance, particularly for map modifications. For instance, modifications of disjoint sets of keys are much less likely to contend on larger maps, and there is no longer any ramp-up time required to achieve low-contention loads from the map.

If you encounter any problems, set GOEXPERIMENT=nosynchashtriemap at build time to switch back to the old implementation and please file an issue.

testing

The new T.Context and B.Context methods return a context that’s canceled after the test completes and before test cleanup functions run.

The new T.Chdir and B.Chdir methods can be used to change the working directory for the duration of a test or benchmark.

text/template

Templates now support range-over-func and range-over-int.

time

Time now implements the encoding.BinaryAppender and encoding.TextAppender interfaces.

Ports

Linux

As announced in the Go 1.23 release notes, Go 1.24 requires Linux kernel version 3.2 or later.

Darwin

Go 1.24 is the last release that will run on macOS 11 Big Sur. Go 1.25 will require macOS 12 Monterey or later.

WebAssembly

The go:wasmexport compiler directive is added for Go programs to export functions to the WebAssembly host.

On WebAssembly System Interface Preview 1 ( GOOS=wasip1 GOARCH=wasm), Go 1.24 supports building a Go program as a reactor/library, by specifying the -buildmode=c-shared build flag.

More types are now permitted as argument or result types for go:wasmimport functions. Specifically, bool, string, uintptr, and pointers to certain types are allowed (see the documentation for detail), along with 32-bit and 64-bit integer and float types, and unsafe.Pointer, which are already allowed. These types are also permitted as argument or result types for go:wasmexport functions.

The support files for WebAssembly have been moved to lib/wasm from misc/wasm.

The initial memory size is significantly reduced, especially for small WebAssembly applications.

Windows

The 32-bit windows/arm port ( GOOS=windows GOARCH=arm) has been marked broken. See issue #70705 for details.

Update Sep 5, 2024 tracked by Updatify

go1.23.1 (released 2024-09-05)

go1.23.1 (released 2024-09-05) includes security fixes to the encoding/gob, go/build/constraint, and go/parser packages, as well as bug fixes to the compiler, the go command, the runtime, and the database/sql, go/types, os, runtime/trace, and unique packages. See the Go 1.23.1 milestone on our issue tracker for details.

Update Aug 13, 2024 tracked by Updatify

go1.23.0 (released 2024-08-13)

Introduction to Go 1.23

The latest Go release, version 1.23, arrives six months after Go 1.22. Most of its changes are in the implementation of the toolchain, runtime, and libraries. As always, the release maintains the Go 1 promise of compatibility. We expect almost all Go programs to continue to compile and run as before.

Changes to the language

The “range” clause in a “for-range” loop now accepts iterator functions of the following types

func(func() bool)
func(func(K) bool)
func(func(K, V) bool)

as range expressions. Calls of the iterator argument function produce the iteration values for the “for-range” loop. For details see the iter package documentation, the language spec, and the Range over Function Types blog post. For motivation see the 2022 “range-over-func” discussion.

Go 1.23 includes preview support for generic type aliases. Building the toolchain with GOEXPERIMENT=aliastypeparams enables this feature within a package. (Using generic alias types across package boundaries is not yet supported.)

Tools

Telemetry

Starting in Go 1.23, the Go toolchain can collect usage and breakage statistics that help the Go team understand how the Go toolchain is used and how well it is working. We refer to these statistics as Go telemetry.

Go telemetry is an opt-in system, controlled by the go telemetry command. By default, the toolchain programs collect statistics in counter files that can be inspected locally but are otherwise unused ( go telemetry local).

To help us keep Go working well and understand Go usage, please consider opting in to Go telemetry by running go telemetry on. In that mode, anonymous counter reports are uploaded to telemetry.go.dev weekly, where they are aggregated into graphs and also made available for download by any Go contributors or users wanting to analyze the data. See “ Go Telemetry ” for more details about the Go Telemetry system.

Go command

Setting the GOROOT_FINAL environment variable no longer has an effect ( #62047). Distributions that install the go command to a location other than $GOROOT/bin/go should install a symlink instead of relocating or copying the go binary.

The new go env -changed flag causes the command to print only those settings whose effective value differs from the default value that would be obtained in an empty environment with no prior uses of the -w flag.

The new go mod tidy -diff flag causes the command not to modify the files but instead print the necessary changes as a unified diff. It exits with a non-zero code if updates are needed.

The go list -m -json command now includes new Sum and GoModSum fields. This is similar to the existing behavior of the go mod download -json command.

The new godebug directive in go.mod and go.work declares a GODEBUG setting to apply for the work module or workspace in use.

Vet

The go vet subcommand now includes the stdversion analyzer, which flags references to symbols that are too new for the version of Go in effect in the referring file. (The effective version is determined by the go directive in the file’s enclosing go.mod file, and by any //go:build constraints in the file.)

For example, it will report a diagnostic for a reference to the reflect.TypeFor function (introduced in go1.22) from a file in a module whose go.mod file specifies go 1.21.

Cgo

cmd/cgo supports the new -ldflags flag for passing flags to the C linker. The go command uses it automatically, avoiding “argument list too long” errors with a very large CGO_LDFLAGS.

Trace

The trace tool now better tolerates partially broken traces by attempting to recover what trace data it can. This functionality is particularly helpful when viewing a trace that was collected during a program crash, since the trace data leading up to the crash will now be recoverable under most circumstances.

Runtime

The traceback printed by the runtime after an unhandled panic or other fatal error now indents the second and subsequent lines of the error message (for example, the argument to panic) by a single tab, so that it can be unambiguously distinguished from the stack trace of the first goroutine. See #64590 for discussion.

Compiler

The build time overhead to building with Profile Guided Optimization has been reduced significantly. Previously, large builds could see 100%+ build time increase from enabling PGO. In Go 1.23, overhead should be in the single digit percentages.

The compiler in Go 1.23 can now overlap the stack frame slots of local variables accessed in disjoint regions of a function, which reduces stack usage for Go applications.

For 386 and amd64, the compiler will use information from PGO to align certain hot blocks in loops. This improves performance an additional 1-1.5% at a cost of an additional 0.1% text and binary size. This is currently only implemented on 386 and amd64 because it has not shown an improvement on other platforms. Hot block alignment can be disabled with -gcflags=[<packages>=]-d=alignhot=0.

Linker

The linker now disallows using a //go:linkname directive to refer to internal symbols in the standard library (including the runtime) that are not marked with //go:linkname on their definitions. Similarly, the linker disallows references to such symbols from assembly code. For backward compatibility, existing usages of //go:linkname found in a large open-source code corpus remain supported. Any new references to standard library internal symbols will be disallowed.

A linker command line flag -checklinkname=0 can be used to disable this check, for debugging and experimenting purposes.

When building a dynamically linked ELF binary (including PIE binary), the new -bindnow flag enables immediate function binding.

Standard library

Timer changes

Go 1.23 makes two significant changes to the implementation of time.Timer and time.Ticker.

First, Timer s and Ticker s that are no longer referred to by the program become eligible for garbage collection immediately, even if their Stop methods have not been called. Earlier versions of Go did not collect unstopped Timer s until after they had fired and never collected unstopped Ticker s.

Second, the timer channel associated with a Timer or Ticker is now unbuffered, with capacity 0. The main effect of this change is that Go now guarantees that for any call to a Reset or Stop method, no stale values prepared before that call will be sent or received after the call. Earlier versions of Go used channels with a one-element buffer, making it difficult to use Reset and Stop correctly. A visible effect of this change is that len and cap of timer channels now returns 0 instead of 1, which may affect programs that poll the length to decide whether a receive on the timer channel will succeed. Such code should use a non-blocking receive instead.

These new behaviors are only enabled when the main Go program is in a module with a go.mod go line using Go 1.23.0 or later. When Go 1.23 builds older programs, the old behaviors remain in effect. The new GODEBUG setting asynctimerchan=1 can be used to revert back to asynchronous channel behaviors even when a program names Go 1.23.0 or later in its go.mod file.

New unique package

The new unique package provides facilities for canonicalizing values (like “interning” or “hash-consing”).

Any value of comparable type may be canonicalized with the new Make[T] function, which produces a reference to a canonical copy of the value in the form of a Handle[T]. Two Handle[T] are equal if and only if the values used to produce the handles are equal, allowing programs to deduplicate values and reduce their memory footprint. Comparing two Handle[T] values is efficient, reducing down to a simple pointer comparison.

Iterators

The new iter package provides the basic definitions for working with user-defined iterators.

The slices package adds several functions that work with iterators:

  • All returns an iterator over slice indexes and values.
  • Values returns an iterator over slice elements.
  • Backward returns an iterator that loops over a slice backward.
  • Collect collects values from an iterator into a new slice.
  • AppendSeq appends values from an iterator to an existing slice.
  • Sorted collects values from an iterator into a new slice, and then sorts the slice.
  • SortedFunc is like Sorted but with a comparison function.
  • SortedStableFunc is like SortFunc but uses a stable sort algorithm.
  • Chunk returns an iterator over consecutive sub-slices of up to n elements of a slice.

The maps package adds several functions that work with iterators:

  • All returns an iterator over key-value pairs from a map.
  • Keys returns an iterator over keys in a map.
  • Values returns an iterator over values in a map.
  • Insert adds the key-value pairs from an iterator to an existing map.
  • Collect collects key-value pairs from an iterator into a new map and returns it.

New structs package

The new structs package provides types for struct fields that modify properties of the containing struct type such as memory layout.

In this release, the only such type is HostLayout which indicates that a structure with a field of that type has a layout that conforms to host platform expectations. HostLayout should be used in types that are passed to, returned from, or accessed via a pointer passed to/from host APIs. Without this marker, struct layout order is not guaranteed by the language spec, though as of Go 1.23 the host and language layouts happen to match.

Minor changes to the library

archive/tar

If the argument to FileInfoHeader implements the new FileInfoNames interface, then the interface methods will be used to set the Uname/Gname of the file header. This allows applications to override the system-dependent Uname/Gname lookup.

crypto/tls

The TLS client now supports the Encrypted Client Hello draft specification. This feature can be enabled by setting the Config.EncryptedClientHelloConfigList field to an encoded ECHConfigList for the host that is being connected to.

The QUICConn type used by QUIC implementations includes new events reporting on the state of session resumption, and provides a way for the QUIC layer to add data to session tickets and session cache entries.

3DES cipher suites were removed from the default list used when Config.CipherSuites is nil. The default can be reverted by adding tls3des=1 to the GODEBUG environment variable.

The experimental post-quantum key exchange mechanism X25519Kyber768Draft00 is now enabled by default when Config.CurvePreferences is nil. The default can be reverted by adding tlskyber=0 to the GODEBUG environment variable. This can be useful when dealing with buggy TLS servers that do not handle large records correctly, causing a timeout during the handshake (see TLS post-quantum TL;DR fail).

Go 1.23 changed the behavior of X509KeyPair and LoadX509KeyPair to populate the Certificate.Leaf field of the returned Certificate. The new x509keypairleaf GODEBUG setting is added for this behavior.

crypto/x509

CreateCertificateRequest now correctly supports RSA-PSS signature algorithms.

CreateCertificateRequest and CreateRevocationList now verify the generated signature using the signer’s public key. If the signature is invalid, an error is returned. This has been the behavior of CreateCertificate since Go 1.16.

The x509sha1 GODEBUG setting will be removed in the next Go major release (Go 1.24). This will mean that crypto/x509 will no longer support verifying signatures on certificates that use SHA-1 based signature algorithms.

The new ParseOID function parses a dot-encoded ASN.1 Object Identifier string. The OID type now implements the encoding.BinaryMarshaler, encoding.BinaryUnmarshaler, encoding.TextMarshaler, encoding.TextUnmarshaler interfaces.

database/sql

Errors returned by driver.Valuer implementations are now wrapped for improved error handling during operations like DB.Query, DB.Exec, and DB.QueryRow.

debug/elf

The debug/elf package now defines PT_OPENBSD_NOBTCFI. This ProgType is used to disable Branch Tracking Control Flow Integrity (BTCFI) enforcement on OpenBSD binaries.

Now defines the symbol type constants STT_RELC, STT_SRELC, and STT_GNU_IFUNC.

encoding/binary

The new Encode and Decode functions are byte slice equivalents to Read and Write. Append allows marshaling multiple data into the same byte slice.

go/ast

The new Preorder function returns a convenient iterator over all the nodes of a syntax tree.

go/types

The Func type, which represents a function or method symbol, now has a Func.Signature method that returns the function’s type, which is always a Signature.

The Alias type now has an Rhs method that returns the type on the right-hand side of its declaration: given type A = B, the Rhs of A is B. ( #66559)

The methods Alias.Origin, Alias.SetTypeParams, Alias.TypeParams, and Alias.TypeArgs have been added. They are needed for generic alias types.

By default, go/types now produces Alias type nodes for type aliases. This behavior can be controlled by the GODEBUG gotypesalias flag. Its default has changed from 0 in Go 1.22 to 1 in Go 1.23.

math/rand/v2

The Uint function and Rand.Uint method have been added. They were inadvertently left out of Go 1.22.

The new ChaCha8.Read method implements the io.Reader interface.

net

The new type KeepAliveConfig permits fine-tuning the keep-alive options for TCP connections, via a new TCPConn.SetKeepAliveConfig method and new KeepAliveConfig fields for Dialer and ListenConfig.

The DNSError type now wraps errors caused by timeouts or cancellation. For example, errors.Is(someDNSErr, context.DeadlineExceedeed) will now report whether a DNS error was caused by a timeout.

The new GODEBUG setting netedns0=0 disables sending EDNS0 additional headers on DNS requests, as they reportedly break the DNS server on some modems.

net/http

Cookie now preserves double quotes surrounding a cookie value. The new Cookie.Quoted field indicates whether the Cookie.Value was originally quoted.

The new Request.CookiesNamed method retrieves all cookies that match the given name.

The new Cookie.Partitioned field identifies cookies with the Partitioned attribute.

The patterns used by ServeMux now allow one or more spaces or tabs after the method name. Previously, only a single space was permitted.

The new ParseCookie function parses a Cookie header value and returns all the cookies which were set in it. Since the same cookie name can appear multiple times the returned Values can contain more than one value for a given key.

The new ParseSetCookie function parses a Set-Cookie header value and returns a cookie. It returns an error on syntax error.

ServeContent, ServeFile, and ServeFileFS now remove the Cache-Control, Content-Encoding, Etag, and Last-Modified headers when serving an error. These headers usually apply to the non-error content, but not to the text of errors.

Middleware which wraps a ResponseWriter and applies on-the-fly encoding, such as Content-Encoding: gzip, will not function after this change. The previous behavior of ServeContent, ServeFile, and ServeFileFS may be restored by setting GODEBUG=httpservecontentkeepheaders=1.

Note that middleware which changes the size of the served content (such as by compressing it) already does not function properly when ServeContent handles a Range request. On-the-fly compression should use the Transfer-Encoding header instead of Content-Encoding.

For inbound requests, the new Request.Pattern field contains the ServeMux pattern (if any) that matched the request. This field is not set when GODEBUG=httpmuxgo121=1 is set.

net/http/httptest

The new NewRequestWithContext method creates an incoming request with a context.Context.

net/netip

In Go 1.22 and earlier, using reflect.DeepEqual to compare an Addr holding an IPv4 address to one holding the IPv4-mapped IPv6 form of that address incorrectly returned true, even though the Addr values were different when comparing with == or Addr.Compare. This bug is now fixed and all three approaches now report the same result.

os

The Stat function now sets the ModeSocket bit for files that are Unix sockets on Windows. These files are identified by having a reparse tag set to IO_REPARSE_TAG_AF_UNIX.

On Windows, the mode bits reported by Lstat and Stat for reparse points changed. Mount points no longer have ModeSymlink set, and reparse points that are not symlinks, Unix sockets, or dedup files now always have ModeIrregular set. This behavior is controlled by the winsymlink setting. For Go 1.23, it defaults to winsymlink=1. Previous versions default to winsymlink=0.

The CopyFS function copies an io/fs.FS into the local filesystem.

On Windows, Readlink no longer tries to normalize volumes to drive letters, which was not always even possible. This behavior is controlled by the winreadlinkvolume setting. For Go 1.23, it defaults to winreadlinkvolume=1. Previous versions default to winreadlinkvolume=0.

On Linux with pidfd support (generally Linux v5.4+), Process -related functions and methods use pidfd (rather than PID) internally, eliminating potential mistargeting when a PID is reused by the OS. Pidfd support is fully transparent to a user, except for additional process file descriptors that a process may have.

path/filepath

The new Localize function safely converts a slash-separated path into an operating system path.

On Windows, EvalSymlinks no longer evaluates mount points, which was a source of many inconsistencies and bugs. This behavior is controlled by the winsymlink setting. For Go 1.23, it defaults to winsymlink=1. Previous versions default to winsymlink=0.

On Windows, EvalSymlinks no longer tries to normalize volumes to drive letters, which was not always even possible. This behavior is controlled by the winreadlinkvolume setting. For Go 1.23, it defaults to winreadlinkvolume=1. Previous versions default to winreadlinkvolume=0.

reflect

The new methods synonymous with the methods of the same name in Value are added to Type:

  1. Type.OverflowComplex
  2. Type.OverflowFloat
  3. Type.OverflowInt
  4. Type.OverflowUint

The new SliceAt function is analogous to NewAt, but for slices.

The Value.Pointer and Value.UnsafePointer methods now support values of kind String.

The new methods Value.Seq and Value.Seq2 return sequences that iterate over the value as though it were used in a for/range loop. The new methods Type.CanSeq and Type.CanSeq2 report whether calling Value.Seq and Value.Seq2, respectively, will succeed without panicking.

runtime/debug

The SetCrashOutput function allows the user to specify an alternate file to which the runtime should write its fatal crash report. It may be used to construct an automated reporting mechanism for all unexpected crashes, not just those in goroutines that explicitly use recover.

runtime/pprof

The maximum stack depth for alloc, mutex, block, threadcreate and goroutine profiles has been raised from 32 to 128 frames.

runtime/trace

The runtime now explicitly flushes trace data when a program crashes due to an uncaught panic. This means that more complete trace data will be available in a trace if the program crashes while tracing is active.

slices

The Repeat function returns a new slice that repeats the provided slice the given number of times.

sync

The Map.Clear method deletes all the entries, resulting in an empty Map. It is analogous to clear.

sync/atomic

The new And and Or operators apply a bitwise AND or OR to the given input, returning the old value.

syscall

The syscall package now defines WSAENOPROTOOPT on Windows.

The GetsockoptInt function is now supported on Windows.

testing/fstest

TestFS now returns a structured error that can be unwrapped (via method Unwrap() []error). This allows inspecting errors using errors.Is or errors.As.

text/template

Templates now support the new “else with” action, which reduces template complexity in some use cases.

time

Parse and ParseInLocation now return an error if the time zone offset is out of range.

On Windows, Timer, Ticker, and functions that put the goroutine to sleep, such as Sleep, got their time resolution improved to 0.5ms instead of 15.6ms.

unicode/utf16

The RuneLen function returns the number of 16-bit words in the UTF-16 encoding of the rune. It returns -1 if the rune is not a valid value to encode in UTF-16.

Ports

Darwin

As announced in the Go 1.22 release notes, Go 1.23 requires macOS 11 Big Sur or later; support for previous versions has been discontinued.

Linux

Go 1.23 is the last release that requires Linux kernel version 2.6.32 or later. Go 1.24 will require Linux kernel version 3.2 or later.

OpenBSD

Go 1.23 adds experimental support for OpenBSD on 64-bit RISC-V ( GOOS=openbsd, GOARCH=riscv64).

ARM64

Go 1.23 introduces a new GOARM64 environment variable, which specifies the minimum target version of the ARM64 architecture at compile time. Allowed values are v8.{0-9} and v9.{0-5}. This may be followed by an option specifying extensions implemented by target hardware. Valid options are ,lse and ,crypto.

The GOARM64 environment variable defaults to v8.0.

RISC-V

Go 1.23 introduces a new GORISCV64 environment variable, which selects the RISC-V user-mode application profile for which to compile. Allowed values are rva20u64 and rva22u64.

The GORISCV64 environment variable defaults to rva20u64.

Wasm

The go_wasip1_wasm_exec script in GOROOT/misc/wasm has dropped support for versions of wasmtime < 14.0.0.

Update Mar 5, 2024 tracked by Updatify

go1.22.1 (released 2024-03-05)

go1.22.1 (released 2024-03-05) includes security fixes to the crypto/x509, html/template, net/http, net/http/cookiejar, and net/mail packages, as well as bug fixes to the compiler, the go command, the runtime, the trace command, and the go/types and net/http packages. See the Go 1.22.1 milestone on our issue tracker for details.

Update Feb 6, 2024 tracked by Updatify

go1.22.0 (released 2024-02-06)

Introduction to Go 1.22

The latest Go release, version 1.22, arrives six months after Go 1.21. Most of its changes are in the implementation of the toolchain, runtime, and libraries. As always, the release maintains the Go 1 promise of compatibility. We expect almost all Go programs to continue to compile and run as before.

Changes to the language

Go 1.22 makes two changes to “for” loops.

  • Previously, the variables declared by a “for” loop were created once and updated by each iteration. In Go 1.22, each iteration of the loop creates new variables, to avoid accidental sharing bugs. The transition support tooling described in the proposal continues to work in the same way it did in Go 1.21.
  • “For” loops may now range over integers. For example: package main import "fmt" func main() { for i := range 10 { fmt.Println(10 - i) } fmt.Println("go1.22 has lift-off!") } See the spec for details.

Go 1.22 includes a preview of a language change we are considering for a future version of Go: range-over-function iterators. Building with GOEXPERIMENT=rangefunc enables this feature.

Tools

Go command

Commands in workspaces can now use a vendor directory containing the dependencies of the workspace. The directory is created by go work vendor, and used by build commands when the -mod flag is set to vendor, which is the default when a workspace vendor directory is present.

Note that the vendor directory’s contents for a workspace are different from those of a single module: if the directory at the root of a workspace also contains one of the modules in the workspace, its vendor directory can contain the dependencies of either the workspace or of the module, but not both.

go get is no longer supported outside of a module in the legacy GOPATH mode (that is, with GO111MODULE=off). Other build commands, such as go build and go test, will continue to work indefinitely for legacy GOPATH programs.

go mod init no longer attempts to import module requirements from configuration files for other vendoring tools (such as Gopkg.lock).

go test -cover now prints coverage summaries for covered packages that do not have their own test files. Prior to Go 1.22 a go test -cover run for such a package would report

? mymod/mypack [no test files]

and now with Go 1.22, functions in the package are treated as uncovered:

mymod/mypack coverage: 0.0% of statements

Note that if a package contains no executable code at all, we can’t report a meaningful coverage percentage; for such packages the go tool will continue to report that there are no test files.

go build commands that invoke the linker now error out if an external (C) linker will be used but cgo is not enabled. (The Go runtime requires cgo support to ensure that it is compatible with any additional libraries added by the C linker.)

Trace

The trace tool’s web UI has been gently refreshed as part of the work to support the new tracer, resolving several issues and improving the readability of various sub-pages. The web UI now supports exploring traces in a thread-oriented view. The trace viewer also now displays the full duration of all system calls.
These improvements only apply for viewing traces produced by programs built with Go 1.22 or newer. A future release will bring some of these improvements to traces produced by older version of Go.

Vet

References to loop variables

The behavior of the vet tool has changed to match the new semantics (see above) of loop variables in Go 1.22. When analyzing a file that requires Go 1.22 or newer (due to its go.mod file or a per-file build constraint), vet no longer reports references to loop variables from within a function literal that might outlive the iteration of the loop. In Go 1.22, loop variables are created anew for each iteration, so such references are no longer at risk of using a variable after it has been updated by the loop.

New warnings for missing values after append

The vet tool now reports calls to append that pass no values to be appended to the slice, such as slice = append(slice). Such a statement has no effect, and experience has shown that is nearly always a mistake.

New warnings for deferring time.Since

The vet tool now reports a non-deferred call to time.Since(t) within a defer statement. This is equivalent to calling time.Now().Sub(t) before the defer statement, not when the deferred function is called. In nearly all cases, the correct code requires deferring the time.Since call. For example:

t := time.Now()
defer log.Println(time.Since(t)) // non-deferred call to time.Since
tmp := time.Since(t); defer log.Println(tmp) // equivalent to the previous defer

defer func() {
  log.Println(time.Since(t)) // a correctly deferred call to time.Since
}()

New warnings for mismatched key-value pairs in log/slog calls

The vet tool now reports invalid arguments in calls to functions and methods in the structured logging package, log/slog, that accept alternating key/value pairs. It reports calls where an argument in a key position is neither a string nor a slog.Attr, and where a final key is missing its value.

Runtime

The runtime now keeps type-based garbage collection metadata nearer to each heap object, improving the CPU performance (latency or throughput) of Go programs by 1–3%. This change also reduces the memory overhead of the majority Go programs by approximately 1% by deduplicating redundant metadata. Some programs may see a smaller improvement because this change adjusts the size class boundaries of the memory allocator, so some objects may be moved up a size class.

A consequence of this change is that some objects’ addresses that were previously always aligned to a 16 byte (or higher) boundary will now only be aligned to an 8 byte boundary. Some programs that use assembly instructions that require memory addresses to be more than 8-byte aligned and rely on the memory allocator’s previous alignment behavior may break, but we expect such programs to be rare. Such programs may be built with GOEXPERIMENT=noallocheaders to revert to the old metadata layout and restore the previous alignment behavior, but package owners should update their assembly code to avoid the alignment assumption, as this workaround will be removed in a future release.

On the windows/amd64 port, programs linking or loading Go libraries built with -buildmode=c-archive or -buildmode=c-shared can now use the SetUnhandledExceptionFilter Win32 function to catch exceptions not handled by the Go runtime. Note that this was already supported on the windows/386 port.

Compiler

Profile-guided Optimization (PGO) builds can now devirtualize a higher proportion of calls than previously possible. Most programs from a representative set of Go programs now see between 2 and 14% improvement at runtime from enabling PGO.

The compiler now interleaves devirtualization and inlining, so interface method calls are better optimized.

Go 1.22 also includes a preview of an enhanced implementation of the compiler’s inlining phase that uses heuristics to boost inlinability at call sites deemed “important” (for example, in loops) and discourage inlining at call sites deemed “unimportant” (for example, on panic paths). Building with GOEXPERIMENT=newinliner enables the new call-site heuristics; see issue #61502 for more info and to provide feedback.

Linker

The linker’s -s and -w flags are now behave more consistently across all platforms. The -w flag suppresses DWARF debug information generation. The -s flag suppresses symbol table generation. The -s flag also implies the -w flag, which can be negated with -w=0. That is, -s -w=0 will generate a binary with DWARF debug information generation but without the symbol table.

On ELF platforms, the -B linker flag now accepts a special form: with -B gobuildid, the linker will generate a GNU build ID (the ELF NT_GNU_BUILD_ID note) derived from the Go build ID.

On Windows, when building with -linkmode=internal, the linker now preserves SEH information from C object files by copying the .pdata and .xdata sections into the final binary. This helps with debugging and profiling binaries using native tools, such as WinDbg. Note that until now, C functions’ SEH exception handlers were not being honored, so this change may cause some programs to behave differently. -linkmode=external is not affected by this change, as external linkers already preserve SEH information.

Bootstrap

As mentioned in the Go 1.20 release notes, Go 1.22 now requires the final point release of Go 1.20 or later for bootstrap. We expect that Go 1.24 will require the final point release of Go 1.22 or later for bootstrap.

Standard library

New math/rand/v2 package

Go 1.22 includes the first “v2” package in the standard library, math/rand/v2. The changes compared to math/rand are detailed in proposal #61716. The most important changes are:

  • The Read method, deprecated in math/rand, was not carried forward for math/rand/v2. (It remains available in math/rand.) The vast majority of calls to Read should use crypto/rand ’s Read instead. Otherwise a custom Read can be constructed using the Uint64 method.
  • The global generator accessed by top-level functions is unconditionally randomly seeded. Because the API guarantees no fixed sequence of results, optimizations like per-thread random generator states are now possible.
  • The Source interface now has a single Uint64 method; there is no Source64 interface.
  • Many methods now use faster algorithms that were not possible to adopt in math/rand because they changed the output streams.
  • The Intn, Int31, Int31n, Int63, and Int64n top-level functions and methods from math/rand are spelled more idiomatically in math/rand/v2: IntN, Int32, Int32N, Int64, and Int64N. There are also new top-level functions and methods Uint32, Uint32N, Uint64, Uint64N, and UintN.
  • The new generic function N is like Int64N or Uint64N but works for any integer type. For example a random duration from 0 up to 5 minutes is rand.N(5*time.Minute).
  • The Mitchell & Reeds LFSR generator provided by math/rand ’s Source has been replaced by two more modern pseudo-random generator sources: ChaCha8 and PCG. ChaCha8 is a new, cryptographically strong random number generator roughly similar to PCG in efficiency. ChaCha8 is the algorithm used for the top-level functions in math/rand/v2. As of Go 1.22, math/rand ’s top-level functions (when not explicitly seeded) and the Go runtime also use ChaCha8 for randomness.

We plan to include an API migration tool in a future release, likely Go 1.23.

New go/version package

The new go/version package implements functions for validating and comparing Go version strings.

Enhanced routing patterns

HTTP routing in the standard library is now more expressive. The patterns used by net/http.ServeMux have been enhanced to accept methods and wildcards.

Registering a handler with a method, like "POST /items/create", restricts invocations of the handler to requests with the given method. A pattern with a method takes precedence over a matching pattern without one. As a special case, registering a handler with "GET" also registers it with "HEAD".

Wildcards in patterns, like /items/{id}, match segments of the URL path. The actual segment value may be accessed by calling the Request.PathValue method. A wildcard ending in “…”, like /files/{path...}, must occur at the end of a pattern and matches all the remaining segments.

A pattern that ends in “/” matches all paths that have it as a prefix, as always. To match the exact pattern including the trailing slash, end it with {$}, as in /exact/match/{$}.

If two patterns overlap in the requests that they match, then the more specific pattern takes precedence. If neither is more specific, the patterns conflict. This rule generalizes the original precedence rules and maintains the property that the order in which patterns are registered does not matter.

This change breaks backwards compatibility in small ways, some obvious—patterns with “{” and “}” behave differently— and some less so—treatment of escaped paths has been improved. The change is controlled by a GODEBUG field named httpmuxgo121. Set httpmuxgo121=1 to restore the old behavior.

Minor changes to the library

As always, there are various minor changes and updates to the library, made with the Go 1 promise of compatibility in mind. There are also various performance improvements, not enumerated here.

archive/tar : The new method Writer.AddFS adds all of the files from an fs.FS to the archive.

archive/zip : The new method Writer.AddFS adds all of the files from an fs.FS to the archive.

bufio : When a SplitFunc returns ErrFinalToken with a nil token, Scanner will now stop immediately. Previously, it would report a final empty token before stopping, which was usually not desired. Callers that do want to report a final empty token can do so by returning []byte{} rather than nil.

cmp : The new function Or returns the first in a sequence of values that is not the zero value.

crypto/tls : ConnectionState.ExportKeyingMaterial will now return an error unless TLS 1.3 is in use, or the extended_master_secret extension is supported by both the server and client. crypto/tls has supported this extension since Go 1.20. This can be disabled with the tlsunsafeekm=1 GODEBUG setting. By default, the minimum version offered by crypto/tls servers is now TLS 1.2 if not specified with config.MinimumVersion, matching the behavior of crypto/tls clients. This change can be reverted with the tls10server=1 GODEBUG setting. By default, cipher suites without ECDHE support are no longer offered by either clients or servers during pre-TLS 1.3 handshakes. This change can be reverted with the tlsrsakex=1 GODEBUG setting.

crypto/x509 : The new CertPool.AddCertWithConstraint method can be used to add customized constraints to root certificates to be applied during chain building. On Android, root certificates will now be loaded from /data/misc/keychain/certs-added as well as /system/etc/security/cacerts. A new type, OID, supports ASN.1 Object Identifiers with individual components larger than 31 bits. A new field which uses this type, Policies, is added to the Certificate struct, and is now populated during parsing. Any OIDs which cannot be represented using a asn1.ObjectIdentifier will appear in Policies, but not in the old PolicyIdentifiers field. When calling CreateCertificate, the Policies field is ignored, and policies are taken from the PolicyIdentifiers field. Using the x509usepolicies=1 GODEBUG setting inverts this, populating certificate policies from the Policies field, and ignoring the PolicyIdentifiers field. We may change the default value of x509usepolicies in Go 1.23, making Policies the default field for marshaling.

database/sql : The new Null[T] type provide a way to scan nullable columns for any column types.

debug/elf : Constant R_MIPS_PC32 is defined for use with MIPS64 systems. Additional R_LARCH_* constants are defined for use with LoongArch systems.

encoding : The new methods AppendEncode and AppendDecode added to each of the Encoding types in the packages encoding/base32, encoding/base64, and encoding/hex simplify encoding and decoding from and to byte slices by taking care of byte slice buffer management. The methods base32.Encoding.WithPadding and base64.Encoding.WithPadding now panic if the padding argument is a negative value other than NoPadding.

encoding/json : Marshaling and encoding functionality now escapes '\b' and '\f' characters as \b and \f instead of \u0008 and \u000c.

go/ast : The following declarations related to syntactic identifier resolution are now deprecated: Ident.Obj, Object, Scope, File.Scope, File.Unresolved, Importer, Package, NewPackage. In general, identifiers cannot be accurately resolved without type information. Consider, for example, the identifier K in T{K: ""}: it could be the name of a local variable if T is a map type, or the name of a field if T is a struct type. New programs should use the go/types package to resolve identifiers; see Object, Info.Uses, and Info.Defs for details. The new ast.Unparen function removes any enclosing parentheses from an expression.

go/types : The new Alias type represents type aliases. Previously, type aliases were not represented explicitly, so a reference to a type alias was equivalent to spelling out the aliased type, and the name of the alias was lost. The new representation retains the intermediate Alias. This enables improved error reporting (the name of a type alias can be reported), and allows for better handling of cyclic type declarations involving type aliases. In a future release, Alias types will also carry type parameter information. The new function Unalias returns the actual type denoted by an Alias type (or any other Type for that matter). Because Alias types may break existing type switches that do not know to check for them, this functionality is controlled by a GODEBUG field named gotypesalias. With gotypesalias=0, everything behaves as before, and Alias types are never created. With gotypesalias=1, Alias types are created and clients must expect them. The default is gotypesalias=0. In a future release, the default will be changed to gotypesalias=1. Clients of go/types are urged to adjust their code as soon as possible to work with gotypesalias=1 to eliminate problems early. The Info struct now exports the FileVersions map which provides per-file Go version information. The new helper method PkgNameOf returns the local package name for the given import declaration. The implementation of SizesFor has been adjusted to compute the same type sizes as the compiler when the compiler argument for SizesFor is "gc". The default Sizes implementation used by the type checker is now types.SizesFor("gc", "amd64"). The start position ( Pos) of the lexical environment block ( Scope) that represents a function body has changed: it used to start at the opening curly brace of the function body, but now starts at the function’s func token.

html/template : JavaScript template literals may now contain Go template actions, and parsing a template containing one will no longer return ErrJSTemplate. Similarly the GODEBUG setting jstmpllitinterp no longer has any effect.

io : The new SectionReader.Outer method returns the ReaderAt, offset, and size passed to NewSectionReader.

log/slog : The new SetLogLoggerLevel function controls the level for the bridge between the slog and log packages. It sets the minimum level for calls to the top-level slog logging functions, and it sets the level for calls to log.Logger that go through slog.

math/big : The new method Rat.FloatPrec computes the number of fractional decimal digits required to represent a rational number accurately as a floating-point number, and whether accurate decimal representation is possible in the first place.

net : When io.Copy copies from a TCPConn to a UnixConn, it will now use Linux’s splice(2) system call if possible, using the new method TCPConn.WriteTo. The Go DNS Resolver, used when building with “-tags=netgo”, now searches for a matching name in the Windows hosts file, located at %SystemRoot%\System32\drivers\etc\hosts, before making a DNS query.

net/http : The new functions ServeFileFS, FileServerFS, and NewFileTransportFS are versions of the existing ServeFile, FileServer, and NewFileTransport, operating on an fs.FS. The HTTP server and client now reject requests and responses containing an invalid empty Content-Length header. The previous behavior may be restored by setting GODEBUG field httplaxcontentlength=1. The new method Request.PathValue returns path wildcard values from a request and the new method Request.SetPathValue sets path wildcard values on a request.

net/http/cgi : When executing a CGI process, the PATH_INFO variable is now always set to the empty string or a value starting with a / character, as required by RFC 3875. It was previously possible for some combinations of Handler.Root and request URL to violate this requirement.

net/netip : The new AddrPort.Compare method compares two AddrPort s.

os : On Windows, the Stat function now follows all reparse points that link to another named entity in the system. It was previously only following IO_REPARSE_TAG_SYMLINK and IO_REPARSE_TAG_MOUNT_POINT reparse points. On Windows, passing O_SYNC to OpenFile now causes write operations to go directly to disk, equivalent to O_SYNC on Unix platforms. On Windows, the ReadDir, File.ReadDir, File.Readdir, and File.Readdirnames functions now read directory entries in batches to reduce the number of system calls, improving performance up to 30%. When io.Copy copies from a File to a net.UnixConn, it will now use Linux’s sendfile(2) system call if possible, using the new method File.WriteTo.

os/exec : On Windows, LookPath now ignores empty entries in %PATH%, and returns ErrNotFound (instead of ErrNotExist) if no executable file extension is found to resolve an otherwise-unambiguous name. On Windows, Command and Cmd.Start no longer call LookPath if the path to the executable is already absolute and has an executable file extension. In addition, Cmd.Start no longer writes the resolved extension back to the Path field, so it is now safe to call the String method concurrently with a call to Start.

reflect : The Value.IsZero method will now return true for a floating-point or complex negative zero, and will return true for a struct value if a blank field (a field named _) somehow has a non-zero value. These changes make IsZero consistent with comparing a value to zero using the language == operator. The PtrTo function is deprecated, in favor of PointerTo. The new function TypeFor returns the Type that represents the type argument T. Previously, to get the reflect.Type value for a type, one had to use reflect.TypeOf((*T)(nil)).Elem(). This may now be written as reflect.TypeFor[T]().

runtime/metrics : Four new histogram metrics /sched/pauses/stopping/gc:seconds, /sched/pauses/stopping/other:seconds, /sched/pauses/total/gc:seconds, and /sched/pauses/total/other:seconds provide additional details about stop-the-world pauses. The “stopping” metrics report the time taken from deciding to stop the world until all goroutines are stopped. The “total” metrics report the time taken from deciding to stop the world until it is started again. The /gc/pauses:seconds metric is deprecated, as it is equivalent to the new /sched/pauses/total/gc:seconds metric. /sync/mutex/wait/total:seconds now includes contention on runtime-internal locks in addition to sync.Mutex and sync.RWMutex.

runtime/pprof : Mutex profiles now scale contention by the number of goroutines blocked on the mutex. This provides a more accurate representation of the degree to which a mutex is a bottleneck in a Go program. For instance, if 100 goroutines are blocked on a mutex for 10 milliseconds, a mutex profile will now record 1 second of delay instead of 10 milliseconds of delay. Mutex profiles also now include contention on runtime-internal locks in addition to sync.Mutex and sync.RWMutex. Contention on runtime-internal locks is always reported at runtime._LostContendedRuntimeLock. A future release will add complete stack traces in these cases. CPU profiles on Darwin platforms now contain the process’s memory map, enabling the disassembly view in the pprof tool.

runtime/trace : The execution tracer has been completely overhauled in this release, resolving several long-standing issues and paving the way for new use-cases for execution traces. Execution traces now use the operating system’s clock on most platforms (Windows excluded) so it is possible to correlate them with traces produced by lower-level components. Execution traces no longer depend on the reliability of the platform’s clock to produce a correct trace. Execution traces are now partitioned regularly on-the-fly and as a result may be processed in a streamable way. Execution traces now contain complete durations for all system calls. Execution traces now contain information about the operating system threads that goroutines executed on. The latency impact of starting and stopping execution traces has been dramatically reduced. Execution traces may now begin or end during the garbage collection mark phase. To allow Go developers to take advantage of these improvements, an experimental trace reading package is available at golang.org/x/exp/trace. Note that this package only works on traces produced by programs built with Go 1.22 at the moment. Please try out the package and provide feedback on the corresponding proposal issue. If you experience any issues with the new execution tracer implementation, you may switch back to the old implementation by building your Go program with GOEXPERIMENT=noexectracer2. If you do, please file an issue, otherwise this option will be removed in a future release.

slices : The new function Concat concatenates multiple slices. Functions that shrink the size of a slice ( Delete, DeleteFunc, Compact, CompactFunc, and Replace) now zero the elements between the new length and the old length. Insert now always panics if the argument i is out of range. Previously it did not panic in this situation if there were no elements to be inserted.

syscall : The syscall package has been frozen since Go 1.4 and was marked as deprecated in Go 1.11, causing many editors to warn about any use of the package. However, some non-deprecated functionality requires use of the syscall package, such as the os/exec.Cmd.SysProcAttr field. To avoid unnecessary complaints on such code, the syscall package is no longer marked as deprecated. The package remains frozen to most new functionality, and new code remains encouraged to use golang.org/x/sys/unix or golang.org/x/sys/windows where possible. On Linux, the new SysProcAttr.PidFD field allows obtaining a PID FD when starting a child process via StartProcess or os/exec. On Windows, passing O_SYNC to Open now causes write operations to go directly to disk, equivalent to O_SYNC on Unix platforms.

testing/slogtest : The new Run function uses sub-tests to run test cases, providing finer-grained control.

Ports

Darwin

On macOS on 64-bit x86 architecture (the darwin/amd64 port), the Go toolchain now generates position-independent executables (PIE) by default. Non-PIE binaries can be generated by specifying the -buildmode=exe build flag. On 64-bit ARM-based macOS (the darwin/arm64 port), the Go toolchain already generates PIE by default.

Go 1.22 is the last release that will run on macOS 10.15 Catalina. Go 1.23 will require macOS 11 Big Sur or later.

ARM

The GOARM environment variable now allows you to select whether to use software or hardware floating point. Previously, valid GOARM values were 5, 6, or 7. Now those same values can be optionally followed by ,softfloat or ,hardfloat to select the floating-point implementation.

This new option defaults to softfloat for version 5 and hardfloat for versions 6 and 7.

Loong64

The loong64 port now supports passing function arguments and results using registers.

The linux/loong64 port now supports the address sanitizer, memory sanitizer, new-style linker relocations, and the plugin build mode.

OpenBSD

Go 1.22 adds an experimental port to OpenBSD on big-endian 64-bit PowerPC ( openbsd/ppc64).

Update Sep 6, 2023 tracked by Updatify

go1.21.1 (released 2023-09-06)

go1.21.1 (released 2023-09-06) includes four security fixes to the cmd/go, crypto/tls, and html/template packages, as well as bug fixes to the compiler, the go command, the linker, the runtime, and the context, crypto/tls, encoding/gob, encoding/xml, go/types, net/http, os, and path/filepath packages. See the Go 1.21.1 milestone on our issue tracker for details.

Update Aug 8, 2023 tracked by Updatify

go1.21.0 (released 2023-08-08)

Introduction to Go 1.21

The latest Go release, version 1.21, arrives six months after Go 1.20. Most of its changes are in the implementation of the toolchain, runtime, and libraries. As always, the release maintains the Go 1 promise of compatibility; in fact, Go 1.21 improves upon that promise. We expect almost all Go programs to continue to compile and run as before.

Go 1.21 introduces a small change to the numbering of releases. In the past, we used Go 1. N to refer to both the overall Go language version and release family as well as the first release in that family. Starting in Go 1.21, the first release is now Go 1. N.0. Today we are releasing both the Go 1.21 language and its initial implementation, the Go 1.21.0 release. These notes refer to “Go 1.21”; tools like go version will report “ go1.21.0 ” (until you upgrade to Go 1.21.1). See “ Go versions ” in the “Go Toolchains” documentation for details about the new version numbering.

Changes to the language

Go 1.21 adds three new built-ins to the language.

  • The new functions min and max compute the smallest (or largest, for max) value of a fixed number of given arguments. See the language spec for details.
  • The new function clear deletes all elements from a map or zeroes all elements of a slice. See the language spec for details.

Package initialization order is now specified more precisely. The new algorithm is:

  • Sort all packages by import path.
  • Repeat until the list of packages is empty: - Find the first package in the list for which all imports are already initialized.
  • Initialize that package and remove it from the list.

This may change the behavior of some programs that rely on a specific initialization ordering that was not expressed by explicit imports. The behavior of such programs was not well defined by the spec in past releases. The new rule provides an unambiguous definition.

Multiple improvements that increase the power and precision of type inference have been made.

  • A (possibly partially instantiated generic) function may now be called with arguments that are themselves (possibly partially instantiated) generic functions. The compiler will attempt to infer the missing type arguments of the callee (as before) and, for each argument that is a generic function that is not fully instantiated, its missing type arguments (new). Typical use cases are calls to generic functions operating on containers (such as slices.IndexFunc) where a function argument may also be generic, and where the type argument of the called function and its arguments are inferred from the container type. More generally, a generic function may now be used without explicit instantiation when it is assigned to a variable or returned as a result value if the type arguments can be inferred from the assignment.
  • Type inference now also considers methods when a value is assigned to an interface: type arguments for type parameters used in method signatures may be inferred from the corresponding parameter types of matching methods.
  • Similarly, since a type argument must implement all the methods of its corresponding constraint, the methods of the type argument and constraint are matched which may lead to the inference of additional type arguments.
  • If multiple untyped constant arguments of different kinds (such as an untyped int and an untyped floating-point constant) are passed to parameters with the same (not otherwise specified) type parameter type, instead of an error, now type inference determines the type using the same approach as an operator with untyped constant operands. This change brings the types inferred from untyped constant arguments in line with the types of constant expressions.
  • Type inference is now precise when matching corresponding types in assignments: component types (such as the elements of slices, or the parameter types in function signatures) must be identical (given suitable type arguments) to match, otherwise inference fails. This change produces more accurate error messages: where in the past type inference may have succeeded incorrectly and lead to an invalid assignment, the compiler now reports an inference error if two types can’t possibly match.

More generally, the description of type inference in the language spec has been clarified. Together, all these changes make type inference more powerful and inference failures less surprising.

Go 1.21 includes a preview of a language change we are considering for a future version of Go: making for loop variables per-iteration instead of per-loop, to avoid accidental sharing bugs. For details about how to try that language change, see the LoopvarExperiment wiki page.

Go 1.21 now defines that if a goroutine is panicking and recover was called directly by a deferred function, the return value of recover is guaranteed not to be nil. To ensure this, calling panic with a nil interface value (or an untyped nil) causes a run-time panic of type *runtime.PanicNilError.

To support programs written for older versions of Go, nil panics can be re-enabled by setting GODEBUG=panicnil=1. This setting is enabled automatically when compiling a program whose main package is in a module that declares go 1.20 or earlier.

Tools

Go 1.21 adds improved support for backwards compatibility and forwards compatibility in the Go toolchain.

To improve backwards compatibility, Go 1.21 formalizes Go’s use of the GODEBUG environment variable to control the default behavior for changes that are non-breaking according to the compatibility policy but nonetheless may cause existing programs to break. (For example, programs that depend on buggy behavior may break when a bug is fixed, but bug fixes are not considered breaking changes.) When Go must make this kind of behavior change, it now chooses between the old and new behavior based on the go line in the workspace’s go.work file or else the main module’s go.mod file. Upgrading to a new Go toolchain but leaving the go line set to its original (older) Go version preserves the behavior of the older toolchain. With this compatibility support, the latest Go toolchain should always be the best, most secure, implementation of an older version of Go. See “ Go, Backwards Compatibility, and GODEBUG ” for details.

To improve forwards compatibility, Go 1.21 now reads the go line in a go.work or go.mod file as a strict minimum requirement: go 1.21.0 means that the workspace or module cannot be used with Go 1.20 or with Go 1.21rc1. This allows projects that depend on fixes made in later versions of Go to ensure that they are not used with earlier versions. It also gives better error reporting for projects that make use of new Go features: when the problem is that a newer Go version is needed, that problem is reported clearly, instead of attempting to build the code and printing errors about unresolved imports or syntax errors.

To make these new stricter version requirements easier to manage, the go command can now invoke not just the toolchain bundled in its own release but also other Go toolchain versions found in the PATH or downloaded on demand. If a go.mod or go.work go line declares a minimum requirement on a newer version of Go, the go command will find and run that version automatically. The new toolchain directive sets a suggested minimum toolchain to use, which may be newer than the strict go minimum. See “ Go Toolchains ” for details.

Go command

The -pgo build flag now defaults to -pgo=auto, and the restriction of specifying a single main package on the command line is now removed. If a file named default.pgo is present in the main package’s directory, the go command will use it to enable profile-guided optimization for building the corresponding program.

The -C dir flag must now be the first flag on the command-line when used.

The new go test option -fullpath prints full path names in test log messages, rather than just base names.

The go test -c flag now supports writing test binaries for multiple packages, each to pkg.test where pkg is the package name. It is an error if more than one test package being compiled has a given package name.

The go test -o flag now accepts a directory argument, in which case test binaries are written to that directory instead of the current directory.

When using an external (C) linker with cgo enabled, the runtime/cgo package is now supplied to the Go linker as an additional dependency to ensure that the Go runtime is compatible with any additional libraries added by the C linker.

Cgo

In files that import "C", the Go toolchain now correctly reports errors for attempts to declare Go methods on C types.

Runtime

When printing very deep stacks, the runtime now prints the first 50 (innermost) frames followed by the bottom 50 (outermost) frames, rather than just printing the first 100 frames. This makes it easier to see how deeply recursive stacks started, and is especially valuable for debugging stack overflows.

On Linux platforms that support transparent huge pages, the Go runtime now manages which parts of the heap may be backed by huge pages more explicitly. This leads to better utilization of memory: small heaps should see less memory used (up to 50% in pathological cases) while large heaps should see fewer broken huge pages for dense parts of the heap, improving CPU usage and latency by up to 1%. A consequence of this change is that the runtime no longer tries to work around a particular problematic Linux configuration setting, which may result in higher memory overheads. The recommended fix is to adjust the OS’s huge page settings according to the GC guide. However, other workarounds are available as well. See the section on max_ptes_none.

As a result of runtime-internal garbage collection tuning, applications may see up to a 40% reduction in application tail latency and a small decrease in memory use. Some applications may also observe a small loss in throughput. The memory use decrease should be proportional to the loss in throughput, such that the previous release’s throughput/memory tradeoff may be recovered (with little change to latency) by increasing GOGC and/or GOMEMLIMIT slightly.

Calls from C to Go on threads created in C require some setup to prepare for Go execution. On Unix platforms, this setup is now preserved across multiple calls from the same thread. This significantly reduces the overhead of subsequent C to Go calls from ~1-3 microseconds per call to ~100-200 nanoseconds per call.

Compiler

Profile-guide optimization (PGO), added as a preview in Go 1.20, is now ready for general use. PGO enables additional optimizations on code identified as hot by profiles of production workloads. As mentioned in the Go command section, PGO is enabled by default for binaries that contain a default.pgo profile in the main package directory. Performance improvements vary depending on application behavior, with most programs from a representative set of Go programs seeing between 2 and 7% improvement from enabling PGO. See the PGO user guide for detailed documentation.

PGO builds can now devirtualize some interface method calls, adding a concrete call to the most common callee. This enables further optimization, such as inlining the callee.

Go 1.21 improves build speed by up to 6%, largely thanks to building the compiler itself with PGO.

Assembler

On amd64, frameless nosplit assembly functions are no longer automatically marked as NOFRAME. Instead, the NOFRAME attribute must be explicitly specified if desired, which is already the behavior on other architectures supporting frame pointers. With this, the runtime now maintains the frame pointers for stack transitions.

The verifier that checks for incorrect uses of R15 when dynamic linking on amd64 has been improved.

Linker

On windows/amd64, the linker (with help from the compiler) now emits SEH unwinding data by default, which improves the integration of Go applications with Windows debuggers and other tools.

In Go 1.21 the linker (with help from the compiler) is now capable of deleting dead (unreferenced) global map variables, if the number of entries in the variable initializer is sufficiently large, and if the initializer expressions are side-effect free.

Standard library

New log/slog package

The new log/slog package provides structured logging with levels. Structured logging emits key-value pairs to enable fast, accurate processing of large amounts of log data. The package supports integration with popular log analysis tools and services.

New testing/slogtest package

The new testing/slogtest package can help to validate slog.Handler implementations.

New slices package

The new slices package provides many common operations on slices, using generic functions that work with slices of any element type.

New maps package

The new maps package provides several common operations on maps, using generic functions that work with maps of any key or element type.

New cmp package

The new cmp package defines the type constraint Ordered and two new generic functions Less and Compare that are useful with ordered types.

Minor changes to the library

As always, there are various minor changes and updates to the library, made with the Go 1 promise of compatibility in mind. There are also various performance improvements, not enumerated here.

archive/tar

The implementation of the io/fs.FileInfo interface returned by Header.FileInfo now implements a String method that calls io/fs.FormatFileInfo.

archive/zip

The implementation of the io/fs.FileInfo interface returned by FileHeader.FileInfo now implements a String method that calls io/fs.FormatFileInfo.

The implementation of the io/fs.DirEntry interface returned by the io/fs.ReadDirFile.ReadDir method of the io/fs.File returned by Reader.Open now implements a String method that calls io/fs.FormatDirEntry.

bytes

The Buffer type has two new methods: Available and AvailableBuffer. These may be used along with the Write method to append directly to the Buffer.

context

The new WithoutCancel function returns a copy of a context that is not canceled when the original context is canceled.

The new WithDeadlineCause and WithTimeoutCause functions provide a way to set a context cancellation cause when a deadline or timer expires. The cause may be retrieved with the Cause function.

The new AfterFunc function registers a function to run after a context has been cancelled.

An optimization means that the results of calling Background and TODO and converting them to a shared type can be considered equal. In previous releases they were always different. Comparing Context values for equality has never been well-defined, so this is not considered to be an incompatible change.

crypto/ecdsa

PublicKey.Equal and PrivateKey.Equal now execute in constant time.

crypto/elliptic

All of the Curve methods have been deprecated, along with GenerateKey, Marshal, and Unmarshal. For ECDH operations, the new crypto/ecdh package should be used instead. For lower-level operations, use third-party modules such as filippo.io/nistec.

crypto/rand

The crypto/rand package now uses the getrandom system call on NetBSD 10.0 and later.

crypto/rsa

The performance of private RSA operations (decryption and signing) is now better than Go 1.19 for GOARCH=amd64 and GOARCH=arm64. It had regressed in Go 1.20.

Due to the addition of private fields to PrecomputedValues, PrivateKey.Precompute must be called for optimal performance even if deserializing (for example from JSON) a previously-precomputed private key.

PublicKey.Equal and PrivateKey.Equal now execute in constant time.

The GenerateMultiPrimeKey function and the PrecomputedValues.CRTValues field have been deprecated. PrecomputedValues.CRTValues will still be populated when PrivateKey.Precompute is called, but the values will not be used during decryption operations.

crypto/sha256

SHA-224 and SHA-256 operations now use native instructions when available when GOARCH=amd64, providing a performance improvement on the order of 3-4x.

crypto/tls

Servers now skip verifying client certificates (including not running Config.VerifyPeerCertificate) for resumed connections, besides checking the expiration time. This makes session tickets larger when client certificates are in use. Clients were already skipping verification on resumption, but now check the expiration time even if Config.InsecureSkipVerify is set.

Applications can now control the content of session tickets.

To reduce the potential for session tickets to be used as a tracking mechanism across connections, the server now issues new tickets on every resumption (if they are supported and not disabled) and tickets don’t bear an identifier for the key that encrypted them anymore. If passing a large number of keys to Conn.SetSessionTicketKeys, this might lead to a noticeable performance cost.

Both clients and servers now implement the Extended Master Secret extension (RFC 7627). The deprecation of ConnectionState.TLSUnique has been reverted, and is now set for resumed connections that support Extended Master Secret.

The new QUICConn type provides support for QUIC implementations, including 0-RTT support. Note that this is not itself a QUIC implementation, and 0-RTT is still not supported in TLS.

The new VersionName function returns the name for a TLS version number.

The TLS alert codes sent from the server for client authentication failures have been improved. Previously, these failures always resulted in a “bad certificate” alert. Now, certain failures will result in more appropriate alert codes, as defined by RFC 5246 and RFC 8446:

  • For TLS 1.3 connections, if the server is configured to require client authentication using RequireAnyClientCert or RequireAndVerifyClientCert, and the client does not provide any certificate, the server will now return the “certificate required” alert.
  • If the client provides a certificate that is not signed by the set of trusted certificate authorities configured on the server, the server will return the “unknown certificate authority” alert.
  • If the client provides a certificate that is either expired or not yet valid, the server will return the “expired certificate” alert.
  • In all other scenarios related to client authentication failures, the server still returns “bad certificate”.

crypto/x509

RevocationList.RevokedCertificates has been deprecated and replaced with the new RevokedCertificateEntries field, which is a slice of RevocationListEntry. RevocationListEntry contains all of the fields in pkix.RevokedCertificate, as well as the revocation reason code.

Name constraints are now correctly enforced on non-leaf certificates, and not on the certificates where they are expressed.

debug/elf

The new File.DynValue method may be used to retrieve the numeric values listed with a given dynamic tag.

The constant flags permitted in a DT_FLAGS_1 dynamic tag are now defined with type DynFlag1. These tags have names starting with DF_1.

The package now defines the constant COMPRESS_ZSTD.

The package now defines the constant R_PPC64_REL24_P9NOTOC.

debug/pe

Attempts to read from a section containing uninitialized data using Section.Data or the reader returned by Section.Open now return an error.

embed

The io/fs.File returned by FS.Open now has a ReadAt method that implements io.ReaderAt.

Calling [FS.Open](/pkg/embed/FS.Open).[Stat](/pkg/io/fs/#File.Stat) will return a type that now implements a String method that calls io/fs.FormatFileInfo.

encoding/binary

The new NativeEndian variable may be used to convert between byte slices and integers using the current machine’s native endianness.

errors

The new ErrUnsupported error provides a standardized way to indicate that a requested operation may not be performed because it is unsupported. For example, a call to os.Link when using a file system that does not support hard links.

flag

The new BoolFunc function and FlagSet.BoolFunc method define a flag that does not require an argument and calls a function when the flag is used. This is similar to Func but for a boolean flag.

A flag definition (via Bool, BoolVar, Int, IntVar, etc.) will panic if Set has already been called on a flag with the same name. This change is intended to detect cases where changes in initialization order cause flag operations to occur in a different order than expected. In many cases the fix to this problem is to introduce a explicit package dependence to correctly order the definition before any Set operations.

go/ast

The new IsGenerated predicate reports whether a file syntax tree contains the special comment that conventionally indicates that the file was generated by a tool.

The new File.GoVersion field records the minimum Go version required by any //go:build or // +build directives.

go/build

The package now parses build directives (comments that start with //go:) in file headers (before the package declaration). These directives are available in the new Package fields Directives, TestDirectives, and XTestDirectives.

go/build/constraint

The new GoVersion function returns the minimum Go version implied by a build expression.

go/token

The new File.Lines method returns the file’s line-number table in the same form as accepted by File.SetLines.

go/types

The new Package.GoVersion method returns the Go language version used to check the package.

hash/maphash

The hash/maphash package now has a pure Go implementation, selectable with the purego build tag.

html/template

The new error ErrJSTemplate is returned when an action appears in a JavaScript template literal. Previously an unexported error was returned.

io/fs

The new FormatFileInfo function returns a formatted version of a FileInfo. The new FormatDirEntry function returns a formatted version of a DirEntry. The implementation of DirEntry returned by ReadDir now implements a String method that calls FormatDirEntry, and the same is true for the DirEntry value passed to WalkDirFunc.

math/big

The new Int.Float64 method returns the nearest floating-point value to a multi-precision integer, along with an indication of any rounding that occurred.

net

On Linux, the net package can now use Multipath TCP when the kernel supports it. It is not used by default. To use Multipath TCP when available on a client, call the Dialer.SetMultipathTCP method before calling the Dialer.Dial or Dialer.DialContext methods. To use Multipath TCP when available on a server, call the ListenConfig.SetMultipathTCP method before calling the ListenConfig.Listen method. Specify the network as "tcp" or "tcp4" or "tcp6" as usual. If Multipath TCP is not supported by the kernel or the remote host, the connection will silently fall back to TCP. To test whether a particular connection is using Multipath TCP, use the TCPConn.MultipathTCP method.

In a future Go release we may enable Multipath TCP by default on systems that support it.

net/http

The new ResponseController.EnableFullDuplex method allows server handlers to concurrently read from an HTTP/1 request body while writing the response. Normally, the HTTP/1 server automatically consumes any remaining request body before starting to write the response, to avoid deadlocking clients which attempt to write a complete request before reading the response. The EnableFullDuplex method disables this behavior.

The new ErrSchemeMismatch error is returned by Client and Transport when the server responds to an HTTPS request with an HTTP response.

The net/http package now supports errors.ErrUnsupported, in that the expression errors.Is(http.ErrNotSupported, errors.ErrUnsupported) will return true.

os

Programs may now pass an empty time.Time value to the Chtimes function to leave either the access time or the modification time unchanged.

On Windows the File.Chdir method now changes the current directory to the file, rather than always returning an error.

On Unix systems, if a non-blocking descriptor is passed to NewFile, calling the File.Fd method will now return a non-blocking descriptor. Previously the descriptor was converted to blocking mode.

On Windows calling Truncate on a non-existent file used to create an empty file. It now returns an error indicating that the file does not exist.

On Windows calling TempDir now uses GetTempPath2W when available, instead of GetTempPathW. The new behavior is a security hardening measure that prevents temporary files created by processes running as SYSTEM to be accessed by non-SYSTEM processes.

On Windows the os package now supports working with files whose names, stored as UTF-16, can’t be represented as valid UTF-8.

On Windows Lstat now resolves symbolic links for paths ending with a path separator, consistent with its behavior on POSIX platforms.

The implementation of the io/fs.DirEntry interface returned by the ReadDir function and the File.ReadDir method now implements a String method that calls io/fs.FormatDirEntry.

The implementation of the io/fs.FS interface returned by the DirFS function now implements the io/fs.ReadFileFS and the io/fs.ReadDirFS interfaces.

path/filepath

The implementation of the io/fs.DirEntry interface passed to the function argument of WalkDir now implements a String method that calls io/fs.FormatDirEntry.

reflect

In Go 1.21, ValueOf no longer forces its argument to be allocated on the heap, allowing a Value ’s content to be allocated on the stack. Most operations on a Value also allow the underlying value to be stack allocated.

The new Value method Value.Clear clears the contents of a map or zeros the contents of a slice. This corresponds to the new clear built-in added to the language.

The SliceHeader and StringHeader types are now deprecated. In new code prefer unsafe.Slice, unsafe.SliceData, unsafe.String, or unsafe.StringData.

regexp

Regexp now defines MarshalText and UnmarshalText methods. These implement encoding.TextMarshaler and encoding.TextUnmarshaler and will be used by packages such as encoding/json.

runtime

Textual stack traces produced by Go programs, such as those produced when crashing, calling runtime.Stack, or collecting a goroutine profile with debug=2, now include the IDs of the goroutines that created each goroutine in the stack trace.

Crashing Go applications can now opt-in to Windows Error Reporting (WER) by setting the environment variable GOTRACEBACK=wer or calling debug.SetTraceback("wer") before the crash. Other than enabling WER, the runtime will behave as with GOTRACEBACK=crash. On non-Windows systems, GOTRACEBACK=wer is ignored.

GODEBUG=cgocheck=2, a thorough checker of cgo pointer passing rules, is no longer available as a debug option. Instead, it is available as an experiment using GOEXPERIMENT=cgocheck2. In particular this means that this mode has to be selected at build time instead of startup time.

GODEBUG=cgocheck=1 is still available (and is still the default).

A new type Pinner has been added to the runtime package. Pinner s may be used to “pin” Go memory such that it may be used more freely by non-Go code. For instance, passing Go values that reference pinned Go memory to C code is now allowed. Previously, passing any such nested reference was disallowed by the cgo pointer passing rules. See the docs for more details.

runtime/metrics

A few previously-internal GC metrics, such as live heap size, are now available. GOGC and GOMEMLIMIT are also now available as metrics.

runtime/trace

Collecting traces on amd64 and arm64 now incurs a substantially smaller CPU cost: up to a 10x improvement over the previous release.

Traces now contain explicit stop-the-world events for every reason the Go runtime might stop-the-world, not just garbage collection.

sync

The new OnceFunc, OnceValue, and OnceValues functions capture a common use of Once to lazily initialize a value on first use.

syscall

On Windows the Fchdir function now changes the current directory to its argument, rather than always returning an error.

On FreeBSD SysProcAttr has a new field Jail that may be used to put the newly created process in a jailed environment.

On Windows the syscall package now supports working with files whose names, stored as UTF-16, can’t be represented as valid UTF-8. The UTF16ToString and UTF16FromString functions now convert between UTF-16 data and WTF-8 strings. This is backward compatible as WTF-8 is a superset of the UTF-8 format that was used in earlier releases.

Several error values match the new errors.ErrUnsupported, such that errors.Is(err, errors.ErrUnsupported) returns true.

  • ENOSYS
  • ENOTSUP
  • EOPNOTSUPP
  • EPLAN9 (Plan 9 only)
  • ERROR_CALL_NOT_IMPLEMENTED (Windows only)
  • ERROR_NOT_SUPPORTED (Windows only)
  • EWINDOWS (Windows only)

testing

The new -test.fullpath option will print full path names in test log messages, rather than just base names.

The new Testing function reports whether the program is a test created by go test.

testing/fstest

Calling [Open](/pkg/testing/fstest/MapFS.Open).[Stat](/pkg/io/fs/#File.Stat) will return a type that now implements a String method that calls io/fs.FormatFileInfo.

unicode

The unicode package and associated support throughout the system has been upgraded to Unicode 15.0.0.

Ports

Darwin

As announced in the Go 1.20 release notes, Go 1.21 requires macOS 10.15 Catalina or later; support for previous versions has been discontinued.

Windows

As announced in the Go 1.20 release notes, Go 1.21 requires at least Windows 10 or Windows Server 2016; support for previous versions has been discontinued.

ARM

When building the Go distribution with GOARCH=arm when not running on an ARM system (that is, when building a cross-compiler to ARM), the default value for the GOARM environment variable is now always set to 7. Previously the default depended on characteristics of the build system.

When not building a cross-compiler, the default value is determined by examining the build system. That was true before and remains true in Go 1.21. What has changed is the behavior when building a cross-compiler.

WebAssembly

The new go:wasmimport directive can now be used in Go programs to import functions from the WebAssembly host.

The Go scheduler now interacts much more efficiently with the JavaScript event loop, especially in applications that block frequently on asynchronous events.

WebAssembly System Interface

Go 1.21 adds an experimental port to the WebAssembly System Interface (WASI), Preview 1 ( GOOS=wasip1, GOARCH=wasm).

As a result of the addition of the new GOOS value “ wasip1 ”, Go files named *_wasip1.go will now be ignored by Go tools except when that GOOS value is being used. If you have existing filenames matching that pattern, you will need to rename them.

ppc64/ppc64le

On Linux, GOPPC64=power10 now generates PC-relative instructions, prefixed instructions, and other new Power10 instructions. On AIX, GOPPC64=power10 generates Power10 instructions, but does not generate PC-relative instructions.

When building position-independent binaries for GOPPC64=power10 GOOS=linux GOARCH=ppc64le, users can expect reduced binary sizes in most cases, in some cases 3.5%. Position-independent binaries are built for ppc64le with the following -buildmode values: c-archive, c-shared, shared, pie, plugin.

loong64

The linux/loong64 port now supports -buildmode=c-archive, -buildmode=c-shared and -buildmode=pie.

Update Jul 11, 2023 tracked by Updatify

go1.20.6 (released 2023-07-11)

go1.20.6 (released 2023-07-11) includes a security fix to the net/http package, as well as bug fixes to the compiler, cgo, the cover tool, the go command, the runtime, and the crypto/ecdsa, go/build, go/printer, net/mail, and text/template packages. See the Go 1.20.6 milestone on our issue tracker for details.

Update Feb 1, 2023 tracked by Updatify

go1.20 (released 2023-02-01)

Introduction to Go 1.20

The latest Go release, version 1.20, arrives six months after Go 1.19. Most of its changes are in the implementation of the toolchain, runtime, and libraries. As always, the release maintains the Go 1 promise of compatibility. We expect almost all Go programs to continue to compile and run as before.

Changes to the language

Go 1.20 includes four changes to the language.

Go 1.17 added conversions from slice to an array pointer. Go 1.20 extends this to allow conversions from a slice to an array: given a slice x, [4]byte(x) can now be written instead of *(*[4]byte)(x).

The unsafe package defines three new functions SliceData, String, and StringData. Along with Go 1.17’s Slice, these functions now provide the complete ability to construct and deconstruct slice and string values, without depending on their exact representation.

The specification now defines that struct values are compared one field at a time, considering fields in the order they appear in the struct type definition, and stopping at the first mismatch. The specification could previously have been read as if all fields needed to be compared beyond the first mismatch. Similarly, the specification now defines that array values are compared one element at a time, in increasing index order. In both cases, the difference affects whether certain comparisons must panic. Existing programs are unchanged: the new spec wording describes what the implementations have always done.

Comparable types (such as ordinary interfaces) may now satisfy comparable constraints, even if the type arguments are not strictly comparable (comparison may panic at runtime). This makes it possible to instantiate a type parameter constrained by comparable (e.g., a type parameter for a user-defined generic map key) with a non-strictly comparable type argument such as an interface type, or a composite type containing an interface type.

Ports

Windows

Go 1.20 is the last release that will run on any release of Windows 7, 8, Server 2008 and Server 2012. Go 1.21 will require at least Windows 10 or Server 2016.

Darwin and iOS

Go 1.20 is the last release that will run on macOS 10.13 High Sierra or 10.14 Mojave. Go 1.21 will require macOS 10.15 Catalina or later.

FreeBSD/RISC-V

Go 1.20 adds experimental support for FreeBSD on RISC-V ( GOOS=freebsd, GOARCH=riscv64).

Tools

Go command

The directory $GOROOT/pkg no longer stores pre-compiled package archives for the standard library: go install no longer writes them, the go build no longer checks for them, and the Go distribution no longer ships them. Instead, packages in the standard library are built as needed and cached in the build cache, just like packages outside GOROOT. This change reduces the size of the Go distribution and also avoids C toolchain skew for packages that use cgo.

The implementation of go test -json has been improved to make it more robust. Programs that run go test -json do not need any updates. Programs that invoke go tool test2json directly should now run the test binary with -v=test2json (for example, go test -v=test2json or ./pkg.test -test.v=test2json) instead of plain -v.

A related change to go test -json is the addition of an event with Action set to start at the beginning of each test program’s execution. When running multiple tests using the go command, these start events are guaranteed to be emitted in the same order as the packages named on the command line.

The go command now defines architecture feature build tags, such as amd64.v2, to allow selecting a package implementation file based on the presence or absence of a particular architecture feature. See go help buildconstraint for details.

The go subcommands now accept -C <dir> to change directory to <dir> before performing the command, which may be useful for scripts that need to execute commands in multiple different modules.

The go build and go test commands no longer accept the -i flag, which has been deprecated since Go 1.16.

The go generate command now accepts -skip <pattern> to skip //go:generate directives matching <pattern>.

The go test command now accepts -skip <pattern> to skip tests, subtests, or examples matching <pattern>.

When the main module is located within GOPATH/src, go install no longer installs libraries for non- main packages to GOPATH/pkg, and go list no longer reports a Target field for such packages. (In module mode, compiled packages are stored in the build cache only, but a bug had caused the GOPATH install targets to unexpectedly remain in effect.)

The go build, go install, and other build-related commands now support a -pgo flag that enables profile-guided optimization, which is described in more detail in the Compiler section below. The -pgo flag specifies the file path of the profile. Specifying -pgo=auto causes the go command to search for a file named default.pgo in the main package’s directory and use it if present. This mode currently requires a single main package to be specified on the command line, but we plan to lift this restriction in a future release. Specifying -pgo=off turns off profile-guided optimization.

The go build, go install, and other build-related commands now support a -cover flag that builds the specified target with code coverage instrumentation. This is described in more detail in the Cover section below.

go version

The go version -m command now supports reading more types of Go binaries, most notably, Windows DLLs built with go build -buildmode=c-shared and Linux binaries without execute permission.

Cgo

The go command now disables cgo by default on systems without a C toolchain. More specifically, when the CGO_ENABLED environment variable is unset, the CC environment variable is unset, and the default C compiler (typically clang or gcc) is not found in the path, CGO_ENABLED defaults to 0. As always, you can override the default by setting CGO_ENABLED explicitly.

The most important effect of the default change is that when Go is installed on a system without a C compiler, it will now use pure Go builds for packages in the standard library that use cgo, instead of using pre-distributed package archives (which have been removed, as noted above) or attempting to use cgo and failing. This makes Go work better in some minimal container environments as well as on macOS, where pre-distributed package archives have not been used for cgo-based packages since Go 1.16.

The packages in the standard library that use cgo are net, os/user, and plugin. On macOS, the net and os/user packages have been rewritten not to use cgo: the same code is now used for cgo and non-cgo builds as well as cross-compiled builds. On Windows, the net and os/user packages have never used cgo. On other systems, builds with cgo disabled will use a pure Go version of these packages.

A consequence is that, on macOS, if Go code that uses the net package is built with -buildmode=c-archive, linking the resulting archive into a C program requires passing -lresolv when linking the C code.

On macOS, the race detector has been rewritten not to use cgo: race-detector-enabled programs can be built and run without Xcode. On Linux and other Unix systems, and on Windows, a host C toolchain is required to use the race detector.

Cover

Go 1.20 supports collecting code coverage profiles for programs (applications and integration tests), as opposed to just unit tests.

To collect coverage data for a program, build it with go build ’s -cover flag, then run the resulting binary with the environment variable GOCOVERDIR set to an output directory for coverage profiles. See the ‘coverage for integration tests’ landing page for more on how to get started. For details on the design and implementation, see the proposal.

Vet

Improved detection of loop variable capture by nested functions

The vet tool now reports references to loop variables following a call to T.Parallel() within subtest function bodies. Such references may observe the value of the variable from a different iteration (typically causing test cases to be skipped) or an invalid state due to unsynchronized concurrent access.

The tool also detects reference mistakes in more places. Previously it would only consider the last statement of the loop body, but now it recursively inspects the last statements within if, switch, and select statements.

New diagnostic for incorrect time formats

The vet tool now reports use of the time format 2006-02-01 (yyyy-dd-mm) with Time.Format and time.Parse. This format does not appear in common date standards, but is frequently used by mistake when attempting to use the ISO 8601 date format (yyyy-mm-dd).

Runtime

Some of the garbage collector’s internal data structures were reorganized to be both more space and CPU efficient. This change reduces memory overheads and improves overall CPU performance by up to 2%.

The garbage collector behaves less erratically with respect to goroutine assists in some circumstances.

Go 1.20 adds a new runtime/coverage package containing APIs for writing coverage profile data at runtime from long-running and/or server programs that do not terminate via os.Exit().

Compiler

Go 1.20 adds preview support for profile-guided optimization (PGO). PGO enables the toolchain to perform application- and workload-specific optimizations based on run-time profile information. Currently, the compiler supports pprof CPU profiles, which can be collected through usual means, such as the runtime/pprof or net/http/pprof packages. To enable PGO, pass the path of a pprof profile file via the -pgo flag to go build, as mentioned above. Go 1.20 uses PGO to more aggressively inline functions at hot call sites. Benchmarks for a representative set of Go programs show enabling profile-guided inlining optimization improves performance about 3–4%. See the PGO user guide for detailed documentation. We plan to add more profile-guided optimizations in future releases. Note that profile-guided optimization is a preview, so please use it with appropriate caution.

The Go 1.20 compiler upgraded its front-end to use a new way of handling the compiler’s internal data, which fixes several generic-types issues and enables type declarations within generic functions and methods.

The compiler now rejects anonymous interface cycles with a compiler error by default. These arise from tricky uses of embedded interfaces and have always had subtle correctness issues, yet we have no evidence that they’re actually used in practice. Assuming no reports from users adversely affected by this change, we plan to update the language specification for Go 1.22 to formally disallow them so tools authors can stop supporting them too.

Go 1.18 and 1.19 saw regressions in build speed, largely due to the addition of support for generics and follow-on work. Go 1.20 improves build speeds by up to 10%, bringing it back in line with Go 1.17. Relative to Go 1.19, generated code performance is also generally slightly improved.

Linker

On Linux, the linker now selects the dynamic interpreter for glibc or musl at link time.

On Windows, the Go linker now supports modern LLVM-based C toolchains.

Go 1.20 uses go: and type: prefixes for compiler-generated symbols rather than go. and type.. This avoids confusion for user packages whose name starts with go.. The debug/gosym package understands this new naming convention for binaries built with Go 1.20 and newer.

Bootstrap

When building a Go release from source and GOROOT_BOOTSTRAP is not set, previous versions of Go looked for a Go 1.4 or later bootstrap toolchain in the directory $HOME/go1.4 ( %HOMEDRIVE%%HOMEPATH%\go1.4 on Windows). Go 1.18 and Go 1.19 looked first for $HOME/go1.17 or $HOME/sdk/go1.17 before falling back to $HOME/go1.4, in anticipation of requiring Go 1.17 for use when bootstrapping Go 1.20. Go 1.20 does require a Go 1.17 release for bootstrapping, but we realized that we should adopt the latest point release of the bootstrap toolchain, so it requires Go 1.17.13. Go 1.20 looks for $HOME/go1.17.13 or $HOME/sdk/go1.17.13 before falling back to $HOME/go1.4 (to support systems that hard-coded the path $HOME/go1.4 but have installed a newer Go toolchain there). In the future, we plan to move the bootstrap toolchain forward approximately once a year, and in particular we expect that Go 1.22 will require the final point release of Go 1.20 for bootstrap.

Standard library

New crypto/ecdh package

Go 1.20 adds a new crypto/ecdh package to provide explicit support for Elliptic Curve Diffie-Hellman key exchanges over NIST curves and Curve25519.

Programs should use crypto/ecdh instead of the lower-level functionality in crypto/elliptic for ECDH, and third-party modules for more advanced use cases.

Wrapping multiple errors

Go 1.20 expands support for error wrapping to permit an error to wrap multiple other errors.

An error e can wrap more than one error by providing an Unwrap method that returns a []error.

The errors.Is and errors.As functions have been updated to inspect multiply wrapped errors.

The fmt.Errorf function now supports multiple occurrences of the %w format verb, which will cause it to return an error that wraps all of those error operands.

The new function errors.Join returns an error wrapping a list of errors.

HTTP ResponseController

The new "net/http".ResponseController type provides access to extended per-request functionality not handled by the "net/http".ResponseWriter interface.

Previously, we have added new per-request functionality by defining optional interfaces which a ResponseWriter can implement, such as Flusher. These interfaces are not discoverable and clumsy to use.

The ResponseController type provides a clearer, more discoverable way to add per-handler controls. Two such controls also added in Go 1.20 are SetReadDeadline and SetWriteDeadline, which allow setting per-request read and write deadlines. For example:

func RequestHandler(w ResponseWriter, r *Request) {
  rc := http.NewResponseController(w)
  rc.SetWriteDeadline(time.Time{}) // disable Server.WriteTimeout when sending a large response
  io.Copy(w, bigData)
}

New ReverseProxy Rewrite hook

The httputil.ReverseProxy forwarding proxy includes a new Rewrite hook function, superseding the previous Director hook.

The Rewrite hook accepts a ProxyRequest parameter, which includes both the inbound request received by the proxy and the outbound request that it will send. Unlike Director hooks, which only operate on the outbound request, this permits Rewrite hooks to avoid certain scenarios where a malicious inbound request may cause headers added by the hook to be removed before forwarding. See issue #50580.

The ProxyRequest.SetURL method routes the outbound request to a provided destination and supersedes the NewSingleHostReverseProxy function. Unlike NewSingleHostReverseProxy, SetURL also sets the Host header of the outbound request.

The ProxyRequest.SetXForwarded method sets the X-Forwarded-For, X-Forwarded-Host, and X-Forwarded-Proto headers of the outbound request. When using a Rewrite, these headers are not added by default.

An example of a Rewrite hook using these features is:

proxyHandler := &httputil.ReverseProxy{
  Rewrite: func(r *httputil.ProxyRequest) {
    r.SetURL(outboundURL) // Forward request to outboundURL.
    r.SetXForwarded()     // Set X-Forwarded-* headers.
    r.Out.Header.Set("X-Additional-Header", "header set by the proxy")
  },
}

ReverseProxy no longer adds a User-Agent header to forwarded requests when the incoming request does not have one.

Minor changes to the library

As always, there are various minor changes and updates to the library, made with the Go 1 promise of compatibility in mind. There are also various performance improvements, not enumerated here.

archive/tar

When the GODEBUG=tarinsecurepath=0 environment variable is set, Reader.Next method will now return the error ErrInsecurePath for an entry with a file name that is an absolute path, refers to a location outside the current directory, contains invalid characters, or (on Windows) is a reserved name such as NUL. A future version of Go may disable insecure paths by default.

archive/zip

When the GODEBUG=zipinsecurepath=0 environment variable is set, NewReader will now return the error ErrInsecurePath when opening an archive which contains any file name that is an absolute path, refers to a location outside the current directory, contains invalid characters, or (on Windows) is a reserved names such as NUL. A future version of Go may disable insecure paths by default.

Reading from a directory file that contains file data will now return an error. The zip specification does not permit directory files to contain file data, so this change only affects reading from invalid archives.

bytes

The new CutPrefix and CutSuffix functions are like TrimPrefix and TrimSuffix but also report whether the string was trimmed.

The new Clone function allocates a copy of a byte slice.

context

The new WithCancelCause function provides a way to cancel a context with a given error. That error can be retrieved by calling the new Cause function.

crypto/ecdsa

When using supported curves, all operations are now implemented in constant time. This led to an increase in CPU time between 5% and 30%, mostly affecting P-384 and P-521.

The new PrivateKey.ECDH method converts an ecdsa.PrivateKey to an ecdh.PrivateKey.

crypto/ed25519

The PrivateKey.Sign method and the VerifyWithOptions function now support signing pre-hashed messages with Ed25519ph, indicated by an Options.HashFunc that returns crypto.SHA512. They also now support Ed25519ctx and Ed25519ph with context, indicated by setting the new Options.Context field.

crypto/rsa

The new field OAEPOptions.MGFHash allows configuring the MGF1 hash separately for OAEP decryption.

crypto/rsa now uses a new, safer, constant-time backend. This causes a CPU runtime increase for decryption operations between approximately 15% (RSA-2048 on amd64) and 45% (RSA-4096 on arm64), and more on 32-bit architectures. Encryption operations are approximately 20x slower than before (but still 5-10x faster than decryption). Performance is expected to improve in future releases. Programs must not modify or manually generate the fields of PrecomputedValues.

crypto/subtle

The new function XORBytes XORs two byte slices together.

crypto/tls

Parsed certificates are now shared across all clients actively using that certificate. The memory savings can be significant in programs that make many concurrent connections to a server or collection of servers sharing any part of their certificate chains.

For a handshake failure due to a certificate verification failure, the TLS client and server now return an error of the new type CertificateVerificationError, which includes the presented certificates.

crypto/x509

ParsePKCS8PrivateKey and MarshalPKCS8PrivateKey now support keys of type *crypto/ecdh.PrivateKey. ParsePKIXPublicKey and MarshalPKIXPublicKey now support keys of type *crypto/ecdh.PublicKey. Parsing NIST curve keys still returns values of type *ecdsa.PublicKey and *ecdsa.PrivateKey. Use their new ECDH methods to convert to the crypto/ecdh types.

The new SetFallbackRoots function allows a program to define a set of fallback root certificates in case an operating system verifier or standard platform root bundle is unavailable at runtime. It will most commonly be used with a new package, golang.org/x/crypto/x509roots/fallback, which will provide an up to date root bundle.

debug/elf

Attempts to read from a SHT_NOBITS section using Section.Data or the reader returned by Section.Open now return an error.

Additional R_LARCH_* constants are defined for use with LoongArch systems.

Additional R_PPC64_* constants are defined for use with PPC64 ELFv2 relocations.

The constant value for R_PPC64_SECTOFF_LO_DS is corrected, from 61 to 62.

debug/gosym

Due to a change of Go’s symbol naming conventions, tools that process Go binaries should use Go 1.20’s debug/gosym package to transparently handle both old and new binaries.

debug/pe

Additional IMAGE_FILE_MACHINE_RISCV* constants are defined for use with RISC-V systems.

encoding/binary

The ReadVarint and ReadUvarint functions will now return io.ErrUnexpectedEOF after reading a partial value, rather than io.EOF.

encoding/xml

The new Encoder.Close method can be used to check for unclosed elements when finished encoding.

The decoder now rejects element and attribute names with more than one colon, such as <a:b:c>, as well as namespaces that resolve to an empty string, such as xmlns:a="".

The decoder now rejects elements that use different namespace prefixes in the opening and closing tag, even if those prefixes both denote the same namespace.

errors

The new Join function returns an error wrapping a list of errors.

fmt

The Errorf function supports multiple occurrences of the %w format verb, returning an error that unwraps to the list of all arguments to %w.

The new FormatString function recovers the formatting directive corresponding to a State, which can be useful in Formatter. implementations.

go/ast

The new RangeStmt.Range field records the position of the range keyword in a range statement.

The new File.FileStart and File.FileEnd fields record the position of the start and end of the entire source file.

go/token

The new FileSet.RemoveFile method removes a file from a FileSet. Long-running programs can use this to release memory associated with files they no longer need.

go/types

The new Satisfies function reports whether a type satisfies a constraint. This change aligns with the new language semantics that distinguish satisfying a constraint from implementing an interface.

html/template

Go 1.20.3 and later disallow actions in ECMAScript 6 template literals. This behavior can be reverted by the GODEBUG=jstmpllitinterp=1 setting.

io

The new OffsetWriter wraps an underlying WriterAt and provides Seek, Write, and WriteAt methods that adjust their effective file offset position by a fixed amount.

io/fs

The new error SkipAll terminates a WalkDir immediately but successfully.

math/big

The math/big package’s wide scope and input-dependent timing make it ill-suited for implementing cryptography. The cryptography packages in the standard library no longer call non-trivial Int methods on attacker-controlled inputs. In the future, the determination of whether a bug in math/big is considered a security vulnerability will depend on its wider impact on the standard library.

math/rand

The math/rand package now automatically seeds the global random number generator (used by top-level functions like Float64 and Int) with a random value, and the top-level Seed function has been deprecated. Programs that need a reproducible sequence of random numbers should prefer to allocate their own random source, using rand.New(rand.NewSource(seed)).

Programs that need the earlier consistent global seeding behavior can set GODEBUG=randautoseed=0 in their environment.

The top-level Read function has been deprecated. In almost all cases, crypto/rand.Read is more appropriate.

mime

The ParseMediaType function now allows duplicate parameter names, so long as the values of the names are the same.

mime/multipart

Methods of the Reader type now wrap errors returned by the underlying io.Reader.

In Go 1.19.8 and later, this package sets limits the size of the MIME data it processes to protect against malicious inputs. Reader.NextPart and Reader.NextRawPart limit the number of headers in a part to 10000 and Reader.ReadForm limits the total number of headers in all FileHeaders to 10000. These limits may be adjusted with the GODEBUG=multipartmaxheaders setting. Reader.ReadForm further limits the number of parts in a form to 1000. This limit may be adjusted with the GODEBUG=multipartmaxparts setting.

net

The LookupCNAME function now consistently returns the contents of a CNAME record when one exists. Previously on Unix systems and when using the pure Go resolver, LookupCNAME would return an error if a CNAME record referred to a name that with no A, AAAA, or CNAME record. This change modifies LookupCNAME to match the previous behavior on Windows, allowing LookupCNAME to succeed whenever a CNAME exists.

Interface.Flags now includes the new flag FlagRunning, indicating an operationally active interface. An interface which is administratively configured but not active (for example, because the network cable is not connected) will have FlagUp set but not FlagRunning.

The new Dialer.ControlContext field contains a callback function similar to the existing Dialer.Control hook, that additionally accepts the dial context as a parameter. Control is ignored when ControlContext is not nil.

The Go DNS resolver recognizes the trust-ad resolver option. When options trust-ad is set in resolv.conf, the Go resolver will set the AD bit in DNS queries. The resolver does not make use of the AD bit in responses.

DNS resolution will detect changes to /etc/nsswitch.conf and reload the file when it changes. Checks are made at most once every five seconds, matching the previous handling of /etc/hosts and /etc/resolv.conf.

net/http

The ResponseWriter.WriteHeader function now supports sending 1xx status codes.

The new Server.DisableGeneralOptionsHandler configuration setting allows disabling the default OPTIONS * handler.

The new Transport.OnProxyConnectResponse hook is called when a Transport receives an HTTP response from a proxy for a CONNECT request.

The HTTP server now accepts HEAD requests containing a body, rather than rejecting them as invalid.

HTTP/2 stream errors returned by net/http functions may be converted to a golang.org/x/net/http2.StreamError using errors.As.

Leading and trailing spaces are trimmed from cookie names, rather than being rejected as invalid. For example, a cookie setting of “name =value” is now accepted as setting the cookie “name”.

A Cookie with an empty Expires field is now considered valid. Cookie.Valid only checks Expires when it is set.

net/netip

The new IPv6LinkLocalAllRouters and IPv6Loopback functions are the net/netip equivalents of net.IPv6loopback and net.IPv6linklocalallrouters.

os

On Windows, the name NUL is no longer treated as a special case in Mkdir and Stat.

On Windows, File.Stat now uses the file handle to retrieve attributes when the file is a directory. Previously it would use the path passed to Open, which may no longer be the file represented by the file handle if the file has been moved or replaced. This change modifies Open to open directories without the FILE_SHARE_DELETE access, which match the behavior of regular files.

On Windows, File.Seek now supports seeking to the beginning of a directory.

os/exec

The new Cmd fields Cancel and WaitDelay specify the behavior of the Cmd when its associated Context is canceled or its process exits with I/O pipes still held open by a child process.

path/filepath

The new error SkipAll terminates a Walk immediately but successfully.

The new IsLocal function reports whether a path is lexically local to a directory. For example, if IsLocal(p) is true, then Open(p) will refer to a file that is lexically within the subtree rooted at the current directory.

reflect

The new Value.Comparable and Value.Equal methods can be used to compare two Value s for equality. Comparable reports whether Equal is a valid operation for a given Value receiver.

The new Value.Grow method extends a slice to guarantee space for another n elements.

The new Value.SetZero method sets a value to be the zero value for its type.

Go 1.18 introduced Value.SetIterKey and Value.SetIterValue methods. These are optimizations: v.SetIterKey(it) is meant to be equivalent to v.Set(it.Key()). The implementations incorrectly omitted a check for use of unexported fields that was present in the unoptimized forms. Go 1.20 corrects these methods to include the unexported field check.

regexp

Go 1.19.2 and Go 1.18.7 included a security fix to the regular expression parser, making it reject very large expressions that would consume too much memory. Because Go patch releases do not introduce new API, the parser returned syntax.ErrInternalError in this case. Go 1.20 adds a more specific error, syntax.ErrLarge, which the parser now returns instead.

runtime/cgo

Go 1.20 adds new Incomplete marker type. Code generated by cgo will use cgo.Incomplete to mark an incomplete C type.

runtime/metrics

Go 1.20 adds new supported metrics, including the current GOMAXPROCS setting ( /sched/gomaxprocs:threads), the number of cgo calls executed ( /cgo/go-to-c-calls:calls), total mutex block time ( /sync/mutex/wait/total:seconds), and various measures of time spent in garbage collection.

Time-based histogram metrics are now less precise, but take up much less memory.

runtime/pprof

Mutex profile samples are now pre-scaled, fixing an issue where old mutex profile samples would be scaled incorrectly if the sampling rate changed during execution.

Profiles collected on Windows now include memory mapping information that fixes symbolization issues for position-independent binaries.

runtime/trace

The garbage collector’s background sweeper now yields less frequently, resulting in many fewer extraneous events in execution traces.

strings

The new CutPrefix and CutSuffix functions are like TrimPrefix and TrimSuffix but also report whether the string was trimmed.

sync

The new Map methods Swap, CompareAndSwap, and CompareAndDelete allow existing map entries to be updated atomically.

syscall

On FreeBSD, compatibility shims needed for FreeBSD 11 and earlier have been removed.

On Linux, additional CLONE_* constants are defined for use with the SysProcAttr.Cloneflags field.

On Linux, the new SysProcAttr.CgroupFD and SysProcAttr.UseCgroupFD fields provide a way to place a child process into a specific cgroup.

testing

The new method B.Elapsed reports the current elapsed time of the benchmark, which may be useful for calculating rates to report with ReportMetric.

Calling T.Run from a function passed to T.Cleanup was never well-defined, and will now panic.

time

The new time layout constants DateTime, DateOnly, and TimeOnly provide names for three of the most common layout strings used in a survey of public Go source code.

The new Time.Compare method compares two times.

Parse now ignores sub-nanosecond precision in its input, instead of reporting those digits as an error.

The Time.MarshalJSON method is now more strict about adherence to RFC 3339.

unicode/utf16

The new AppendRune function appends the UTF-16 encoding of a given rune to a uint16 slice, analogous to utf8.AppendRune.