Go 1.24 Release Notes
DRAFT RELEASE NOTES — Introduction to Go 1.24
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.
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 -u tool
or to install them into your GOBIN directory with go install tool
.
Executables created by go run
and the new behavior for 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 by setting
GODEBUG=gotestjsonbuildtext=1
.
The new GOAUTH
environment variable provides a flexible way to authenticate
with private modules. 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
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.
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.
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 #59719.
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.
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
.
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.
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.
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.
New crypto/hkdf package
The new crypto/hkdf
package implements the HMAC-based Extract-and-Expand
Key Derivation Function (HKDF) as defined in RFC 5869. It is based on the pre-existing
golang.org/x/crypto/hkdf
package.
New crypto/mlkem package
The new crypto/mlkem
package implements ML-KEM (formerly known as
Kyber), as specified in NIST FIPS 203.
New crypto/pbkdf2 package
The new crypto/pbkdf2
package implements the key derivation function
PBKDF2 as defined in RFC 2898 / PKCS #5 v2.0. It is based on the pre-existing
golang.org/x/crypto/pbkdf2
package.
New crypto/sha3 package
The new crypto/sha3
package implements the SHA-3 hash function, and SHAKE and
cSHAKE extendable-output functions. It is based on the pre-existing
golang.org/x/crypto/sha3
package.
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 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 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/cipher
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.
The new NewGCMWithRandomNonce
function returns an AEAD
that implements
AES-GCM by generating a random nonce during Seal and prepending it to the
ciphertext.
crypto/fips140
TODO: FIPS 140 will be covered in its own section. TODO: accepted proposal #70200 (from CL 629196, CL 629198, CL 629201, CL 629996)
crypto/md5
The value returned by md5.New
now also implements the encoding.BinaryAppender
interface.
crypto/rand
The Read
function, and the Read
method of Reader
, are now
defined to never fail.
They will always return nil
as the error
result.
If something somehow goes wrong while reading random numbers,
the program will irrecoverably crash.
This change was made because all supported systems now provide
sources of random bytes that never fail.
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.
Setting GODEBUG=rsa1024min=0
or including //go:debug rsa1024min=0
in a
source file restores the old behavior, but we recommend doing so only in tests,
if necessary. A new GenerateKey
example provides an easy-to-use standard
2048-bit test key.
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 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.
crypto/tls
The ClientHelloInfo
struct passed to Config.GetCertificate
now includes an Extensions
field, which can be useful for fingerprinting TLS clients.
The TLS server now supports Encrypted Client Hello (ECH). This feature can be
enabled by populating the Config.EncryptedClientHelloKeys
field.
crypto/tls
now supports the post-quantum X25519MLKEM768
key exchange. 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.
crypto/x509
The x509sha1
GODEBUG setting has been removed. Certificate.Verify
will no
longer consider SHA-1 based signatures valid when this GODEBUG setting is set.
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 by setting
GODEBUG=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 by RFC 5280 and
RFC 9618. In order to enable policy validation,
VerifyOptions.CertificatePolicies
must be set to an acceptable set of policy
OIDs
. When enabled, 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 keys that were previously accepted.
Use GODEBUG=x509rsacrt=0
to revert to recomputing them.
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 set GODEBUG=randseednop=0
. For more background see
the 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.
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
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
.
Windows
The windows/arm port (GOOS=windows
GOARCH=arm
) has been marked broken.
See issue #70705 for details.