Go 1.24 is not yet released. These are work-in-progress release notes. Go 1.24 is expected to be released in February 2025.
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.
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 -u 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 includes versioning information in the compiled binary. If a local VCS tag is available, the main module's version will be set from that tag. If no local VCS tag is available, a pseudo-version will be generated. A +dirty suffix will be appended if there are uncommitted VCS changes present. 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 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.
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.
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.
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 #59719.
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.
The new AddCleanup
function attaches a cleanup function to a pointer. Once the object that the pointer points to is no longer reachable, the runtime will call the function. AddCleanup
is a finalization mechanism that is more flexible and less error-prone than SetFinalizer
. Unlike SetFinalizer
, it does not resurrect the object it is attached to for finalization and multiple cleanups may be attached to a single object. New code should prefer AddCleanup
over SetFinalizer
.
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).
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.
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.
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.
os.Root.Open
opens a file for reading.os.Root.Create
creates a file.os.Root.OpenFile
is the generalized open call.os.Root.Mkdir
creates a directory.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 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.
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.
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
.
The new experimental testing/synctest
package provides support for testing concurrent code.
synctest.Run
function starts a group of goroutines in an isolated “bubble”. Within the bubble, time
package functions operate on a fake clock.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.
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 the byte slice s.SplitSeq
returns an iterator over all substrings of s separated by sep.SplitAfterSeq
returns an iterator over substrings of s split after each instance of sep.FieldsSeq
returns an iterator over substrings of s split around runs of whitespace characters, as defined by unicode.IsSpace.FieldsFuncSeq
returns an iterator over substrings of s split around runs of Unicode code points satisfying f(c).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 rand 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
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
.
The package now rejects more invalid keys, and GenerateKey
may return new errors for broken random sources. See also the changes to crypto/x509
below.
SignPKCS1v15
and VerifyPKCS1v15
now support SHA-512/224, SHA-512/256, and SHA-3.
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.
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 several new constants, types, and methods to add support for handling dynamic versions and version flags in ELF (Executable and Linkable Format) files:
Several new types have been introduced:
DynamicVersion
struct represents a dynamic version entry in the ELF file.DynamicVersionDep
struct represents a dependency of a dynamic version.DynamicVersionNeed
struct represents a required dynamic version in the ELF file.DynamicVersionFlag
is a new type defined as uint16, representing flags for dynamic versions.VER_FLG_BASE
version definition of the file.VER_FLG_WEAK
weak version identifier.VER_FLG_INFO
reference exists for informational purposes.SymbolVersionFlag
is a new type defined as uint8, representing version flags for ELF symbols.VerFlagNone
no flags.VerFlagLocal
symbol has local scope.VerFlagGlobal
symbol has global scope.VerFlagHidden
symbol is hidden.The following methods have been added:
File.DynamicVersionNeeds
method returns a list of dynamic version needs in the ELF file, representing dependencies required by the executable.File.DynamicVersions
retrieves a list of dynamic versions defined in the ELF file.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.
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.
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
New function Comparable
returns the hash of a comparable value. New function WriteComparable
adds a comparable value to the data hashed by a Hash
.
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 the string s.SplitSeq
returns an iterator over all substrings of s separated by sep.SplitAfterSeq
returns an iterator over substrings of s split after each instance of sep.FieldsSeq
returns an iterator over substrings of s split around runs of whitespace characters, as defined by unicode.IsSpace.FieldsFuncSeq
returns an iterator over substrings of s split around runs of Unicode code points satisfying f(c).sync
The implementation of sync.Map
has been changed, improving overall performance and resolving some long-standing issues. 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.
As announced in the Go 1.23 release notes, Go 1.24 requires Linux kernel version 3.2 or later.
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.
The go:wasmexport
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 proposal 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 windows/arm port (GOOS=windows
GOARCH=arm
) has been marked broken. See issue #70705 for details.