Go Updates & Release Notes
55 updates curated from 68 sources by the Releasebot Team. Last updated: Jul 7, 2026
- Jul 7, 2026
- Date parsed from source:Jul 7, 2026
- First seen by Releasebot:Jul 7, 2026
Go 1.27 Release Candidate 2 is released
Go releases go1.27rc2, a Go 1.27 release candidate that focuses on early testing and two security fixes. It addresses an os.Root symlink escape on Unix and a crypto/tls Encrypted Client Hello privacy leak, while inviting users to validate the prerelease build.
Hello gophers,
We have just released go1.27rc2, a release candidate version of Go 1.27.
It is cut from release-branch.go1.27 at the revision tagged go1.27rc2.
This release includes 2 security fixes following the security policy:
os: Root escape via symlink plus trailing slash
On Unix systems, opening a file in an os.Root improperly
followed symlinks to locations outside of the Root when
the final path component of the a path is a symbolic link
and the path ends in /.For example, root.Open("symlink/") would open "symlink"
even when "symlink" is a symbolic link pointing outside of the root.On Unix, openat(fd, path, O_NOFOLLOW) will follow symlinks
in path when path ends in a /. Root failed to account for
this behavior, permitting paths with a trailing / to escape.It now properly sanitizes the path parameter provided to openat.
Thanks to Mundur (https://github.com/M0nd0R) for reporting this issue.
This is CVE-2026-39822 and Go issue https://go.dev/issue/79005.
crypto/tls: Encrypted Client Hello privacy leak
The Encrypted Client Hello implementation would leak the pre-shared key
identities during the handshake, allowing a passive network observer who can
collect handshakes to de-anonymize the hostname of the server, even when ECH was
being used.Thanks to Coia Prant (github.com/rbqvq) for reporting this issue.
This is CVE-2026-42505 and Go issue https://go.dev/issue/79282.
Please try your production load tests and unit tests with the new version.
Your help testing these pre-release versions is invaluable.
Report any problems using the issue tracker:
https://go.dev/issue/newPlease consider opting in to Go telemetry if you haven't already.
Go telemetry helps validate this release candidate and future Go releases.
You can opt in by running the following command:
$ go telemetry onIf you have Go installed already, an easy way to try go1.27rc2
is by using the go command:$ go install golang.org/dl/go1.27rc2@latest $ go1.27rc2 downloadYou can download binary and source distributions from the usual place:
https://go.dev/dl/#go1.27rc2To find out what has changed in Go 1.27, read the draft release notes:
https://tip.golang.org/doc/go1.27Cheers,
Junyang and David for the Go team
Original source - Jul 7, 2026
- Date parsed from source:Jul 7, 2026
- First seen by Releasebot:Jul 7, 2026
[security] Go 1.26.5 and Go 1.25.12 are released
Go releases 1.26.5 and 1.25.12, delivering minor point updates with two security fixes for os Root symlink escape and a crypto/tls Encrypted Client Hello privacy leak.
Hello gophers,
We have just released Go versions 1.26.5 and 1.25.12, minor point releases.
These releases include 2 security fixes following the security policy:
os: Root escape via symlink plus trailing slash
On Unix systems, opening a file in an os.Root improperly followed symlinks to locations outside of the Root when the final path component of the a path is a symbolic link and the path ends in /.
For example, root.Open("symlink/") would open "symlink" even when "symlink" is a symbolic link pointing outside of the root.
On Unix, openat(fd, path, O_NOFOLLOW) will follow symlinks in path when path ends in a /. Root failed to account for this behavior, permitting paths with a trailing / to escape.
It now properly sanitizes the path parameter provided to openat.
Thanks to Mundur (https://github.com/M0nd0R) for reporting this issue.
This is CVE-2026-39822 and Go issue https://go.dev/issue/79005.
crypto/tls: Encrypted Client Hello privacy leak
The Encrypted Client Hello implementation would leak the pre-shared key identities during the handshake, allowing a passive network observer who can collect handshakes to de-anonymize the hostname of the server, even when ECH was being used.
Thanks to Coia Prant (github.com/rbqvq) for reporting this issue.
This is CVE-2026-42505 and Go issue https://go.dev/issue/79282.
View the release notes for more information:
https://go.dev/doc/devel/release#go1.26.5You can download binary and source distributions from the Go website:
https://go.dev/dl/To compile from source using a Git clone, update to the release with
git checkout go1.26.5 and build as usual.Thanks to everyone who contributed to the releases.
Cheers,
Original source
Junyang and David for the Go team All of your release notes in one feed
Join Releasebot and get updates from Google and hundreds of other software products.
- Jun 18, 2026
- Date parsed from source:Jun 18, 2026
- First seen by Releasebot:Jun 19, 2026
Go 1.27 Release Candidate 1 is released
Go releases go1.27rc1, a release candidate for Go 1.27, inviting developers to test production loads and unit tests, share feedback, and try the new build through the usual download and go command paths.
Hello gophers,
We have just released go1.27rc1, a release candidate version of Go 1.27.
It is cut from release-branch.go1.27 at the revision tagged go1.27rc1.
Please try your production load tests and unit tests with the new version.
Your help testing these pre-release versions is invaluable.Report any problems using the issue tracker:
https://go.dev/issue/newPlease consider opting in to
Go telemetry
if you haven't already.
Go telemetry helps validate this release candidate and future Go releases.
You can opt in by running the following command:$ go telemetry onIf you have Go installed already, an easy way to try go1.27rc1
is by using the go command:$ go install golang.org/dl/go1.27rc1@latest $ go1.27rc1 downloadYou can download binary and source distributions from the usual place:
https://go.dev/dl/#go1.27rc1To find out what has changed in Go 1.27, read the draft release notes:
https://tip.golang.org/doc/go1.27Cheers,
Dmitri and Cherry for the Go team
Original source - Jun 2, 2026
- Date parsed from source:Jun 2, 2026
- First seen by Releasebot:Jun 3, 2026
Go 1.26.4 and Go 1.25.11 are released
Go releases 1.26.4 and 1.25.11 with three security fixes that improve MIME header handling, sanitize net/textproto errors, and reduce quadratic hostname verification cost in crypto/x509.
Hello gophers,
We have just released Go versions 1.26.4 and 1.25.11, minor point releases.
These releases include 3 security fixes following the security policy:
mime: quadratic complexity in WordDecoder.DecodeHeader
Decoding a maliciously-crafted MIME header containing many invalid
encoded-words could consume excessive CPU.
The MIME decoder now better handles this case.
Thanks to p4p3r (https://hackerone.com/p4p3r_hak) for reporting this issue.
This is CVE-2026-42504 and Go issue https://go.dev/issue/79217.net/textproto: arbitrary input are included in errors without any escaping
When returning errors, functions in the net/textproto package would
include its input as part of the error, without any escaping. Note that
said input is often controlled by external parties when using this
package naturally. For example, a net/http client uses ReadMIMEHeader
when parsing the headers it receive from a server.
As a result, an attacker could inject arbitrary content into the error.
Practically, this can result in an attacker injecting misleading
content, terminal control bytes, etc. into a victim's output or logs.
This is CVE-2026-42507 and Go issue https://go.dev/issue/79346crypto/x509: split candidate hostname only once
(*x509.Certificate).VerifyHostname previously called matchHostnames in a loop
over all DNS Subject Alternative Name (SAN) entries. This caused
strings.Split(host, ".") to execute repeatedly on the same input hostname.
With a large DNS SAN list, verification costs scaled quadratically based on the
number of SAN entries multiplied by the hostname's label count. Because
x509.Verify validates hostnames before building the certificate chain, this
overhead occurred even for untrusted certificates.
Thanks to Jakub Ciolek (https://ciolek.dev) for reporting this issue.
This is CVE-2026-27145 and https://go.dev/issue/79694.
View the release notes for more information:
https://go.dev/doc/devel/release#go1.26.4You can download binary and source distributions from the Go website:
https://go.dev/dl/To compile from source using a Git clone, update to the release with
git checkout go1.26.4
and build as usual.
Thanks to everyone who contributed to the releases.
Cheers,
The Go team
Original source - May 22, 2026
- Date parsed from source:May 22, 2026
- First seen by Releasebot:May 22, 2026
[security] Vulnerabilities in golang.org/x/crypto
Go tags golang.org/x/crypto v0.52.0 with a broad SSH security update, fixing panic, denial-of-service, authorization bypass, and constraint enforcement issues across ssh, ssh/agent, and ssh/knownhosts.
Ahoy gophers,
We have tagged version v0.52.0 of golang.org/x/crypto in order to address the following security issues:
ssh/agent: pathological inputs can lead to client panic
For certain crafted inputs, a
ed25519.PrivateKeywas created by casting malformed wire bytes, leading to a panic when used.Thanks to NCC Group Cryptography Services, sponsored by Teleport for reporting this issue.
This is CVE-2026-46598 and Go issue https://go.dev/issue/79596.
ssh: byte arithmetic causes underflow and panic
An incorrectly placed cast from bytes to int allowed for server-side panic in the AES-GCM packet decoder for well-crafted inputs.
Thanks to Maciej Kawka for reporting this issue.
This is CVE-2026-46597 and Go issue https://go.dev/issue/79561.
ssh: bypass of certificate restrictions
When an SSH server authentication callback returned PartialSuccessError with non-nil Permissions, those permissions were silently discarded, potentially dropping certificate restrictions such as force-command after a second factor succeeded. Returning non-nil Permissions with PartialSuccessError now results in a connection error.
Thanks to NCC Group Cryptography Services, sponsored by Teleport for reporting this issue.
This is CVE-2026-39828 and Go issue https://go.dev/issue/79562.
ssh: server panic during CheckHostKey/Authenticate
SSH servers which use CertChecker as a public key callback without setting IsUserAuthority or IsHostAuthority could be caused to panic by a client presenting a certificate. CertChecker now returns an error instead of panicking when these callbacks are nil.
Thanks to NCC Group Cryptography Services, sponsored by Teleport for reporting this issue.
This is CVE-2026-39835 and Go issue https://go.dev/issue/79563.
ssh/agent: key constraints not enforced
The in-memory keyring returned by NewKeyring() silently accepted keys with the ConfirmBeforeUse constraint but never enforced it. The key would sign without any confirmation prompt, with no indication to the caller that the constraint was not in effect. NewKeyring() now returns an error when unsupported constraints are requested.
Thanks to NCC Group Cryptography Services, sponsored by Teleport for reporting this issue.
This is CVE-2026-39833 and Go issue https://go.dev/issue/79436.
ssh/agent: agent constraints dropped when forwarding keys
When adding a key to a remote agent constraint extensions such as [email protected] were not serialized in the request. Destination restrictions were silently stripped when forwarding keys, allowing unrestricted use of the key on the remote host. The client now serializes all constraint extensions. Additionally, the in-memory keyring returned by NewKeyring() now rejects keys with unsupported constraint extensions instead of silently ignoring them.
Thanks to NCC Group Cryptography Services, sponsored by Teleport for reporting this issue.
This is CVE-2026-39832 and Go issue https://go.dev/issue/79435.
ssh: memory leak when rejecting channels can lead to DoS
An authenticated SSH client that repeatedly opened channels which were rejected by the server caused unbounded memory growth, eventually crashing the server process and affecting all connected users. Rejected channels are now properly removed from the connection's internal state and released for garbage collection.
Thanks to Ziyan Zhou for reporting this issue.
This is CVE-2026-39827 and Go issue https://go.dev/issue/35127.
ssh: client can cause server deadlock on unexpected responses
A malicious SSH peer could send unsolicited global request responses to fill an internal buffer, blocking the connection's read loop. The blocked goroutine could not be released by calling Close(), resulting in a resource leak per connection. Unsolicited global responses are now discarded.
Thanks to NCC Group Cryptography Services, sponsored by Teleport for reporting this issue.
This is CVE-2026-39830 and Go issue https://go.dev/issue/79564.
ssh: pathological RSA/DSA parameters may cause DoS
The RSA and DSA public key parsers did not enforce size limits on key parameters. A crafted public key with an excessively large modulus or DSA parameter could cause several minutes of CPU consumption during signature verification. This could be triggered by unauthenticated clients during public key authentication. RSA moduli are now limited to 8192 bits, and DSA parameters are validated per FIPS 186-2.
Thanks to NCC Group Cryptography Services, sponsored by Teleport for reporting this issue.
This is CVE-2026-39829 and Go issue https://go.dev/issue/79565.
ssh: bypass of FIDO/U2F security keys physical interaction
The Verify() method for FIDO/U2F security key types ([email protected], [email protected]) did not check the User Presence flag. Signatures generated without physical touch were accepted, allowing unattended use of a hardware security key. To restore the previous behavior, return a "no-touch-required" extension in Permissions.Extensions from PublicKeyCallback.
Thanks to NCC Group Cryptography Services, sponsored by Teleport for reporting this issue.
This is CVE-2026-39831 and Go issue https://go.dev/issue/79566.
ssh: infinite loop on large channel writes
When writing data larger than 4GB in a single Write call on an SSH channel, an integer overflow in the internal payload size calculation caused the write loop to spin indefinitely, sending empty packets without making progress. The size comparison now uses int64 to prevent truncation.
Thanks to NCC Group Cryptography Services, sponsored by Teleport for reporting this issue.
This is CVE-2026-39834 and Go issue https://go.dev/issue/79567.
ssh/knownhosts: auth bypass via unenforced @revoked status
Previously, a revoked
SignatureKeybelonging to a CA was not correctly checked for revocation. Now, both thekeyandkey.SignatureKeyare checked for @revoked.This is CVE-2026-42508 and Go issue https://go.dev/issue/79568.
ssh: VerifiedPublicKeyCallback permissions skip enforcement
Previously, CVE-2024-45337 fixed an authorization bypass for misused ssh server configurations; if any other type of callback is passed other than public key, then the source-address validation would be skipped.
This is CVE-2026-46595 and Go issue https://go.dev/issue/79570.
Cheers,
Go Security Team
Original source Similar to Go with recent updates:
- Gemini updates350 release notes · Latest Jul 10, 2026
- Antigravity updates37 release notes · Latest Jun 25, 2026
- Gemini API updates131 release notes · Latest Jul 6, 2026
- Claude updates114 release notes · Latest Jul 9, 2026
- Gemini CLI updates153 release notes · Latest Jul 8, 2026
- Anthropic updates52 release notes · Latest Jul 9, 2026
- May 22, 2026
- Date parsed from source:May 22, 2026
- First seen by Releasebot:May 22, 2026
[security] Vulnerabilities in golang.org/x/image
Go tags golang.org/x/image v0.41.0 with security fixes for BMP and TIFF decoding, preventing a palette-index panic and limiting PackBits decompression to reduce resource abuse.
Hello gophers,
We have tagged version v0.41.0 of golang.org/x/image in order to address the following security issues:
x/image/bmp: panic when reading out of bound palette index
Decoding a paletted BMP file with an out-of-range palette index would result in a panic when accessing pixels in the invalid image. Decoding now correctly returns an error in this case. This is CVE-2026-42500 and Go issue https://go.dev/issue/79576.
x/image/tiff: excessive resource consumption in PackBits decompression
The TIFF decoder did not place a limit on the size of PackBits-compressed data. A maliciously-crafted image could exploit this to cause a small image (both in terms of pixel width/height and encoded size) to make the decoder decode large amounts of compressed data. The decoder now limits the amount of PackBits-compressed data it will decompress. Thanks to Uuganbayar Lkhamsuren for reporting this issue. This is CVE-2026-33809 and Go issue https://go.dev/issue/79577.
Cheers,
Go Security team
Original source - May 2026
- No date parsed from source.
- First seen by Releasebot:May 22, 2026
[security] Vulnerabilities in golang.org/x/net
Go releases golang.org/x/net v0.55.0 with security fixes for the HTML parser and idna package, addressing XSS risks, privilege escalation, and a potential denial of service.
Hello gophers,
We have tagged version v0.55.0 of golang.org/x/net in order to address the following security issues:
html: incorrect handling of namespaced elements in foreign content
The HTML parser mishandled certain namespaced elements in foreign content,
causing them to be incorrectly rendered. This can lead to XSS when rendering
parsed HTML.Thanks to ensy for reporting this issue.
This is CVE-2026-42506 and Go issue https://go.dev/issue/79571.
x/net/idna: failure to reject ASCII-only Punycode-encoded labels
The ToASCII and ToUnicode functions incorrectly accepted Punycode-encoded labels
that decode to an ASCII-only label. For example, ToUnicode("xn--example-.com")
incorrectly returned the name "example.com" rather than an error.The idna package implements the processing algorithm from UTS 46.
Older versions of UTS 46 included a specification bug which permitted
multiple ASCII labels to decode to the same Unicode label.
UTS 46 revision 33 fixed the specification bug.
The idna package now implements the updated specification.This behavior can lead to privilege escalation in programs using the idna package.
For example, a program which performs privilege checks on the ASCII hostname
may reject "example.com" but permit "xn--example-.com". If that program subsequently
converts the ASCII hostname to Unicode, it will inadvertently permits access
to the Unicode name "example.com".Thanks to KC1zs4 (https://github.com/KC1zs4) for reporting this issue.
This is CVE-2026-39821 and Go issue https://go.dev/issue/78760.
html: incorrect handling of HTML elements in foreign content
The HTML parser mishandled certain HTML elements in foreign content, causing
them to be incorrectly rendered. This can lead to XSS when rendering parsed
HTML.Thanks to Tristan Madani for reporting this issue.
This is CVE-2026-42502 and Go issue https://go.dev/issue/79572.
html: denial of service when parsing arbitrary HTML
Due to the use of a cubic complexity algorithm during the HTML tree construction
stage, parsing arbitrary HTML can consume excessive CPU time.Thanks to IPC Labs for reporting this issue.
This is CVE-2026-25680 and Go issue https://go.dev/issue/79573.
html: incorrect handling of character references in DOCTYPE nodes
The HTML parser mishandled character references in DOCTYPE nodes, causing
them to be incorrectly rendered. This can lead to XSS when rendering parsed
HTML.Thanks to ensy for reporting this issue.
This is CVE-2026-25681 and Go issue https://go.dev/issue/79574.
html: duplicate attributes can cause XSS
The HTML parser did not properly handle multiple duplicate attributes, causing
the parser to misparse certain HTML trees. This can cause XSS when rendering
parsed HTML.Thanks to ensy for reporting this issue.
This is CVE-2026-27136 and Go issue https://go.dev/issue/79575.
Cheers,
Original source
Go Security team - May 21, 2026
- Date parsed from source:May 21, 2026
- First seen by Releasebot:May 22, 2026
Vulnerability in golang.org/x/sys
Go ships a security fix for x/sys on Windows, correcting NewNTUnicodeString overflow handling and returning an error for long strings.
Howdy gophers,
We have tagged version v0.45.0 of golang.org/x/sys in order to address a security issue.
windows: integer overflow in NewNTUnicodeString
NewNTUnicodeString did not check for string length overflow.
When provided with a string that overflows the maximum size of a
NTUnicodeString (a 16-bit number of bytes), it returned a truncated
string rather than an error.It now correctly returns an error when provided with a too-long string.
This is CVE-2026-39824 and Go issue https://go.dev/issue/78916.
Cheers,
Go Security Team
Original source - May 21, 2026
- Date parsed from source:May 21, 2026
- First seen by Releasebot:May 22, 2026
Introducing the pkg.go.dev API
Go launches the official pkg.go.dev API, giving developers direct programmatic access to Go module metadata, package search, symbols, versions, imports, and vulnerabilities. It also ships a pkgsite-cli reference client and a stable, GET-only interface built for tools and AI workflows.
Since its inception, pkg.go.dev has established itself as the Go community’s primary resource for package documentation and discovery. While we initially prioritized creating a comprehensive and highly accessible web interface for users, the need for programmatic access has become increasingly clear. Developers building tools, IDE integrations, and automated workflows have historically relied on fragile workarounds like web scraping to access this data. To better address these evolving requirements, we are now expanding our platform to provide robust, direct access to the information our community needs.
Today, we are excited to introduce the official pkg.go.dev API — a service interface for querying metadata about published Go modules. This launch is a direct response to years of community feedback. Furthermore, the need for a formalized interface has become even more acute with the rise of AI-assisted coding. Tools can now access the specific, high-fidelity context needed to reason about the Go ecosystem with greater precision.
The service interface
Built for stability and efficient caching, the API uses a stateless, GET-only architecture. Primary endpoints are currently hosted under the /v1beta path. Following a period of community feedback and confirmed stability, we intend to transition toward a formal v1 release.
For a complete interactive reference of all endpoints, query parameters, and response shapes, see the pkg.go.dev/api specification. The machine-readable API contract is also published directly as an OpenAPI specification.
Core endpoints
Endpoint | Description
/v1beta/package/{path} | Information about the package at {path}.
/v1beta/module/{path} | Information about the module at {path}.
/v1beta/versions/{path} | Versions of the module at {path}.
/v1beta/packages/{path} | Information about packages of the module at {path}.
/v1beta/search?q={query} | Search results for a given query.
/v1beta/symbols/{path} | List of symbols declared by the package at {path}.
/v1beta/imported-by/{path} | Paths of packages importing the package at {path}.
/v1beta/vulns/{path} | Vulnerabilities of the module or package at {path}.One design principle for this API is “precision over convenience.” For context, when go mod tidy encounters an import of a package that isn’t provided by an existing dependency of the main module, it applies the “longest module path” rule to determine which module is needed. (The fact that two or more modules could provide the package is what makes it possible to later carve out a submodule without breaking existing programs.) The pkg.go.dev web interface follows a similar convention when choosing which package to display for a given package path. By contrast, the pkg.go.dev API requires the module to be specified unambiguously. If a package path is ambiguous because it exists in multiple modules, the API returns a list of candidates and reports an error asking the client to be more specific.
For example, a package imported as example.com/a/b/c could be provided by module example.com/a or by example.com/a/b. While the pkg.go.dev web interface will automatically resolve the “longest module path” (example.com/a/b), a client querying the API must specify the module explicitly to avoid an ambiguous resolution error.
Specifying versions
For endpoints that retrieve package, module, or symbol information, you can specify the desired version using the optional version query parameter. The API returns information about the latest version of the module or package by default. The parameter supports:
- Semantic Versions: Retrieve data for a specific release tag (e.g., ?version=v1.2.3 or ?version=v0.6.0).
- Branch Names: Reference default development branches—specifically master or main (e.g., ?version=master). The API will automatically resolve the branch to its corresponding pseudo-version. Note that custom or arbitrary branch names are not supported.
If the version parameter is omitted, the API defaults to resolving the request against the latest tagged version of the package or module.
Example: raw API request
To retrieve structured metadata for a specific package directly (using jq for formatting):
$ curl https://pkg.go.dev/v1beta/package/github.com/google/go-cmp/cmp | jq . { "modulePath": "github.com/google/go-cmp", "version": "v0.7.0", "isLatest": true, "isStandardLibrary": false, "goos": "all", "goarch": "all", "path": "github.com/google/go-cmp/cmp", "name": "cmp", "synopsis": "Package cmp determines equality of values.", "isRedistributable": true }To query a specific branch version (like master) and see it resolve automatically to its corresponding pseudo-version:
$ curl -s "https://pkg.go.dev/v1beta/package/github.com/google/go-cmp/cmp?version=master" | jq '{path, version}' { "path": "github.com/google/go-cmp/cmp", "version": "v0.7.1-0.20260310220054-34c9473539b8" }The pkgsite-cli reference implementation
To demonstrate how to interact with our API, we are providing a reference client implementation: pkgsite-cli. This implementation serves as a practical example for developers looking to build their own integrations, showing how to handle the data directly from the terminal. Please be aware that as the API continues to evolve, the interface and behavior of this command may change.
To get started, install the command:
$ go install golang.org/x/pkgsite/cmd/internal/pkgsite-cli@latestTo search for packages:
$ pkgsite-cli search "uuid" github.com/google/uuid Module: github.com/google/[email protected] Synopsis: Package uuid generates and inspects UUIDs. ... moreTo inspect a specific package:
$ pkgsite-cli package github.com/google/go-cmp/cmp github.com/google/go-cmp/cmp Name: cmp Module: github.com/google/go-cmp Version: v0.7.0 (latest) Synopsis: Package cmp determines equality of values.To see which packages import a specific package:
$ pkgsite-cli package --imported-by github.com/google/go-cmp/cmp github.com/google/go-cmp/cmp Name: cmp Module: github.com/google/go-cmp Version: v0.7.0 (latest) Synopsis: Package cmp determines equality of values. Imported by: cloud.google.com/go/internal/testutil cuelang.org/go/internal/cuetxtar chainguard.dev/apko/pkg/build/types ... moreTo list symbols declared by a package:
$ pkgsite-cli package --symbols github.com/google/go-cmp/cmp github.com/google/go-cmp/cmp Name: cmp Module: github.com/google/go-cmp Version: v0.7.0 (latest) Synopsis: Package cmp determines equality of values. Symbols: type Indirect struct{} type MapIndex struct{} type Option interface{} ... moreTo list versions of a module:
$ pkgsite-cli module -versions github.com/google/go-cmp github.com/google/go-cmp Version: v0.7.0 (latest) Repository: https://github.com/google/go-cmp Has go.mod: yes Redistributable: yes Versions: v0.7.0 v0.6.0 v0.5.9 ... moreTo list both versions and packages of a module:
$ pkgsite-cli module -packages -versions github.com/google/go-cmp github.com/google/go-cmp Version: v0.7.0 (latest) Repository: https://github.com/google/go-cmp Has go.mod: yes Redistributable: yes Versions: v0.7.0 v0.6.0 v0.5.9 ... more Packages: github.com/google/go-cmp/cmp Package cmp determines equality of values. github.com/google/go-cmp/cmp/cmpopts Package cmpopts provides common options for the cmp package. ... moreThe command handles pagination and formatting, allowing you to focus on the data you need for your scripts or manual investigation. To learn more, please visit pkgsite-cli’s documentation.
Stability and the future
This concludes our brief tour of the pkg.go.dev API. While we plan to expand the interface’s capabilities over time, we are committed to maintaining backward compatibility so that existing integrations continue to function seamlessly. (Note that command line interface of the pkgsite-cli reference client is not yet stable.) We welcome your feedback via our issue tracker, and we look forward to seeing the new tools and workflows the community will build.
Original source - May 2026
- No date parsed from source.
- First seen by Releasebot:May 7, 2026
[security] Go 1.26.3 and Go 1.25.10 are released
Go releases 1.26.3 and 1.25.10 as minor point updates packed with 11 security fixes, strengthening checksum validation, HTTP handling, templates, networking, and command safety across the toolchain.
Hello gophers,
We have just released Go versions 1.26.3 and 1.25.10, minor point releases.
These releases include 11 security fixes following the security policy:
cmd/go: malicious module proxy can bypass checksum database
A malicious module proxy could exploit a flaw in the go command's
validation of module checksums to bypass checksum database validation.
This vulnerability affects any user using an untrusted module proxy
(GOMODPROXY) or checksum database (GOSUMDB).A malicious module proxy can serve altered versions of the Go toolchain.
When selecting a different version of the Go toolchain than the
currently installed toolchain (due to the GOTOOLCHAIN environment variable,
or a go.work or go.mod with a toolchain line), the go command will download
and execute a toolchain provided by the module proxy. A malicious module
proxy can bypass checksum database validation for this downloaded
toolchain.Since this vulnerability affects the security of toolchain downloads,
setting GOTOOLCHAIN to a fixed version is not sufficient. You must upgrade
your base Go toolchain.The go tool always validates the hash of a toolchain before executing it,
so fixed versions will refuse to execute any cached, altered versions of the
toolchain.The go tool trusts go.sum files to contain accurate hashes of the current
module's dependencies. A malicious proxy exploiting this vulnerability to
serve an altered module will have caused an incorrect hash to be recorded
in the go.sum. Users who have configured a non-trusted GOPROXY can determine
if they have been affected by running "rm go.sum ; go mod tidy ; go mod verify",
which will revalidate all dependencies of the current module.The specific flaw in more detail:
The go command consults the checksum database to validate downloaded modules,
when a module is not listed in the go.sum file. It verifies that the module hash
reported by the checksum database matches the hash of the downloaded module.
If, however, the checksum database returns a successful response that contains
no entry for the module, the go command incorrectly permitted validation to succeed.A module proxy may mirror or proxy the checksum database, in which case the go
command will not connect to the checksum database directly. Checksums reported
by the checksum database are cryptographically signed, so a malicious proxy
cannot alter the reported checksum for a module. However, a proxy which returns
an empty checksum response, or a checksum response for an unrelated module,
could cause the go command to proceed as if a downloaded module has been validated.The go command now properly checks checksum database responses to ensure
that the expected module signature is present, not just that if a signature is
present it matches the expectation.Thanks to Mundur (https://github.com/M0nd0R) for reporting this issue.
This is CVE-2026-42501 and Go issue https://go.dev/issue/79070.
net/http/httputil: ReverseProxy forwards queries with more than urlmaxqueryparams parameters
When used with a Rewrite function, or a Director function which parses query parameters,
ReverseProxy sanitizes the forwarded request to remove query parameters which are not
parsed by url.ParseQuery. ReverseProxy did not take ParseQuery's limit on the total number
of query parameters (controlled by GODEBUG=urlmaxqueryparams=N) into account.This could permit ReverseProxy to forward a request containing a query parameter
that was not visible to the Rewrite function.For example, the query "a1=x&a2=x&...&a10000=x&hidden=y" could forward the parameter
"hidden=y" while hiding it from the proxy's Rewrite function.ReverseProxy now avoids forwarding parameters that exceed the ParseQuery limit.
This is CVE-2026-39825 and Go issue https://go.dev/issue/78948.
net: panic in Dial and LookupPort when handling NUL byte on Windows
The Dial and LookupPort functions would panic on Windows when provided
with an input containing a NUL (0). These functions now return an error
rather than panicking.This is CVE-2026-39836 and Go issue https://go.dev/issue/79006.
net/mail: quadratic string concatenation in consumePhrase
Pathological inputs could cause DoS through consumePhrase
when parsing an email address according to RFC 5322.This is CVE-2026-42499 and Go issue https://go.dev/issue/78987.
net/mail: quadratic string concatentation in consumeComment
Well-crafted inputs reaching ParseAddress, ParseAddressList,
and ParseDate were able to trigger excessive CPU exhaustion
and memory allocations.This is CVE-2026-39820 and Go issue https://go.dev/issue/78566.
cmd/go: "go bug" follows symlinks in predictable temporary filenames
The "go bug" command wrote to two files with predictable names in
the system temporary directory (for example, "/tmp").
An attacker with access to the temporary directory could create a
symlink in one of these names, causing "go bug" to overwrite the
target of the symlink.The "go bug" command now uses os.MkdirTemp to create a safe
working directory.Thanks to Harshit Gupta (Mr HAX) for reporting this issue.
This is CVE-2026-39819 and Go issue https://go.dev/issue/78584.
cmd/go: "go tool pack" does not sanitize output paths
The "go tool pack" subcommand is a minimal version of the Unix ar utility.
It is used by the compiler as an internal tool with known-good inputs.
The "pack" subcommand did not sanitize output filenames.When invoked to extract a malicious archive file, it could write
files to arbitrary locations on the filesystem.The "pack" subcommand now refuses to extract files with names
containing any directory components.Thanks to Harshit Gupta (Mr HAX) for reporting this issue.
This is CVE-2026-39817 and Go issue https://go.dev/issue/78778.
net/http: infinite loop in HTTP/2 transport when given bad SETTINGS_MAX_FRAME_SIZE
When processing HTTP/2 SETTINGS frames, transport will enter an infinite loop of
writing CONTINUATION frames if it receives a SETTINGS_MAX_FRAME_SIZE with a
value of 0.This allows potential DoS against a client by a malicious server. HTTP/2
transport now properly checks that the received SETTINGS_MAX_FRAME_SIZE is
valid.Thanks to Marwan Atia ([email protected]) for reporting this issue.
This is CVE-2026-33814 and Go issue https://go.dev/issue/78476.
html/template: escaper bypass leads to XSS
If a trusted template author were to write a
tag containing an empty type attribute or a type attribute with an ASCII whitespace, the execution of
the template would incorrectly escape any data passed
into the block.Thanks to Mundur (https://github.com/M0nd0R) for reporting this issue.
This is CVE-2026-39826 and Go issue https://go.dev/issue/78981.
net: crash when handling long CNAME response
When using LookupCNAME with the cgo DNS resolver,
a very long CNAME response could trigger a double-free of C memory
and a crash. The double-free has been fixed.Thanks to hamayanhamayan for reporting this issue.
This is CVE-2026-33811 and Go issue https://go.dev/issue/78803.
html/template: bypass of meta content URL escaping causes XSS
CVE-2026-27142 fixed a vulnerability in which URLs were not
correctly escaped inside of a tag's attribute.If the URL content were to insert ASCII whitespaces around the = rune inside of the attribute, the escaper would
fail to similarly escape it, leading to XSS.Dynamic inputs to a tag's attribute are now
whitespace sanitized prior to escaping.Thanks to Samy Ghannad for reporting this issue.
This is CVE-2026-39823 and Go issue https://go.dev/issue/78913.
View the release notes for more information:
https://go.dev/doc/devel/release#go1.26.3You can download binary and source distributions from the Go website:
https://go.dev/dl/To compile from source using a Git clone, update to the release with
git checkout go1.26.3 and build as usual.Thanks to everyone who contributed to the releases.
Cheers,
Original source
Cherry and Michael for the Go team - May 4, 2026
- Date parsed from source:May 4, 2026
- First seen by Releasebot:May 5, 2026
[security] Go 1.26.3 and Go 1.25.10 pre-announcement
Go announces upcoming 1.26.3 and 1.25.10 security releases with private standard library and toolchain fixes.
Hello gophers,
We plan to issue Go 1.26.3 and Go 1.25.10 during US business hours on Thursday, May 7.
These minor releases include PRIVATE security fixes to the standard library and the toolchain, covering the following CVEs:
- CVE-2026-39836
- CVE-2026-42501
Following our security policy, this is the pre-announcement of those releases.
Thanks,
Cherry and Michael for the Go team
Original source - Apr 7, 2026
- Date parsed from source:Apr 7, 2026
- First seen by Releasebot:Apr 8, 2026
Go 1.26.2 and Go 1.25.9 are released
Go releases 1.26.2 and 1.25.9 with 10 security fixes, strengthening compiler safety, TLS handling, certificate validation, archive parsing, and template escaping while addressing a Linux Root.Chmod symlink issue.
Hello gophers,
We have just released Go versions 1.26.2 and 1.25.9, minor point releases.
These releases include 10 security fixes following the security policy:
os: Root.Chmod can follow symlinks out of the root on Linux
On Linux, if the target of Root.Chmod is replaced with a symlink while the chmod operation is in progress, Chmod could operate on the target of the symlink, even when the target lies outside the root.
The Linux fchmodat syscall silently ignores the AT_SYMLINK_NOFOLLOW flag, which Root.Chmod uses to avoid symlink traversal. Root.Chmod checks its target before acting and returns an error if the target is a symlink lying outside the root, so the impact is limited to cases where the target is replaced with a symlink between the check and operation.
On Linux, Root.Chmod now uses the fchmodat2 syscall when available, and an workaround using /proc/self/fd otherwise.
Thanks to Uuganbayar Lkhamsuren for reporting this issue.
This is CVE-2026-32282 and Go issue https://go.dev/issue/78293.html/template: JS template literal context incorrectly tracked
Context was not properly tracked across template branches for JS template literals, leading to possibly incorrect escaping of content when branches were used.
Additionally template actions within JS template literals did not properly track the brace depth, leading to incorrect escaping being applied.
These issues could cause actions within JS template literals to be incorrectly or improperly escaped, leading to XSS vulnerabilities.
This only affects templates that use template actions within JS template literals.
This is CVE-2026-32289 and Go issue https://go.dev/issue/78331.crypto/x509: excluded DNS constraints not properly applied to wildcard domains
When verifying a certificate chain containing excluded DNS constraints, these constraints are not correctly applied to wildcard DNS SANs which use a different case than the constraint.
For example, if a certificate contains the DNS name "*.example.com" and the excluded DNS name "EXAMPLE.COM", the constraint will not be applied.
This only affects validation of otherwise trusted certificate chains, issued by a root CA in the VerifyOptions.Roots CertPool, or in the system certificate pool.
This issue only affects Go 1.26.
Thank you to Riyas from Saintgits College of Engineering, k1rnt, @1seal for reporting this issue.
This is CVE-2026-33810 and Go issue https://go.dev/issue/78332.cmd/compile: no-op interface conversion bypasses overlap checking
Previously, the compiler failed to unwrap pointers contained within a no-op interface conversion leading to an incorrect determination of a non-overlapping move.
To prevent unsafe move operations, the compiler will now unwrap all such conversions before considering a move non-overlapping.
Thank you to Jakub Ciolek - https://ciolek.dev/ for reporting this issue.
This is CVE-2026-27144 and Go issue https://go.dev/issue/78371.cmd/compile: possible memory corruption after bound check elimination
Previously, slices and arrays accessed using induction variables were sometimes incorrectly proved in-bound. If the induction variable used for indexing were to overflow or underflow, it could allow access to memory beyond the scope of the original slice or array.
To prevent this behavior, the compiler ensures that any mutated induction variable that overflows/underflows with respect to its loop condition is not used for bound check elimination.
Thank you to Jakub Ciolek - https://ciolek.dev/ for reporting this issue.
This is CVE-2026-27143 and Go issue https://go.dev/issue/78333.archive/tar: unbounded allocation when parsing old format GNU sparse map
tar.Reader could allocate an unbounded amount of memory when reading a maliciously-crafted archive containing a large number of sparse regions encoded in the "old GNU sparse map" format.
We now limit both the number of old GNU sparse map extension blocks, and the total number of sparse file entries, regardless of encoding.
Thanks to Colin Walters ([email protected]) who initially reported this issue.
Thanks also to Uuganbayar Lkhamsuren (https://github.com/uug4na) and Jakub Ciolek who additionally reported this issue.
This is CVE-2026-32288 and Go issue https://go.dev/issue/78301.crypto/tls: multiple key update handshake messages can cause connection to deadlock
If one side of the TLS connection sends multiple key update messages post-handshake in a single record, the connection can deadlock, causing uncontrolled consumption of resources. This can lead to a denial of service.
This only affects TLS 1.3.
Thank you to Jakub Ciolek - https://ciolek.dev/ for reporting this issue.
This is CVE-2026-32283 and Go issue https://go.dev/issue/78334.cmd/go: trust layer bypass when using cgo and SWIG
A well-crafted SWIG source file could take advantage of a file-naming convention used inside the trust boundary of the cgo compiler. Doing so could result in arbitrary code execution during build time.
SWIG files are disallowed from using this convention.
Thank you to Juho Forsén of Mattermost for reporting this issue.
This is CVE-2026-27140 and Go issue https://go.dev/issue/78335.crypto/x509: unexpected work during chain building
During chain building, the amount of work that is done is not correctly limited when a large number of intermediate certificates are passed in VerifyOptions.Intermediates, which can lead to a denial of service. This affects both direct users of crypto/x509 and users of crypto/tls.
Thank you to Jakub Ciolek - https://ciolek.dev/ for reporting this issue.
This is CVE-2026-32280 and Go issue https://go.dev/issue/78282.crypto/x509: inefficient policy validation
Validating certificate chains which use policies is unexpectedly inefficient when certificates in the chain contain a very large number of policy mappings, possibly causing denial of service.
This only affects validation of otherwise trusted certificate chains, issued by a root CA in the VerifyOptions.Roots CertPool, or in the system certificate pool.
Thank you to Jakub Ciolek - https://ciolek.dev/ for reporting this issue.
This is CVE-2026-32281 and Go issue https://go.dev/issue/78281.
View the release notes for more information:
https://go.dev/doc/devel/release#go1.26.2You can download binary and source distributions from the Go website:
https://go.dev/dl/To compile from source using a Git clone, update to the release with git checkout go1.26.2 and build as usual.
Thanks to everyone who contributed to the releases.
Cheers,
Original source
David and Junyang for the Go team - Mar 10, 2026
- Date parsed from source:Mar 10, 2026
- First seen by Releasebot:Mar 11, 2026
//go:fix inline and the source-level inliner
Google presents Go 1.26 with an all-new source-level inliner powering the go fix tool for self-service migrations and safe code updates. The feature tour explains inlining, side effects, and examples like replacing ioutil.ReadFile, framing a tidier, more automated path to modern Go code.
Alan Donovan
10 March 2026
Source-level inlining
Go 1.26 contains an all-new implementation of the
go fix
subcommand, designed to help you keep your Go code up-to-date and modern. For an introduction, start by reading our
recent post
on the topic. In this post, we’ll look at one particular feature, the source-level inliner.While
go fix
has several bespoke modernizers for specific new language and library features, the source-level inliner is the first fruit of our efforts to provide “
self-service
” modernizers and analyzers. It enables any package author to express simple API migrations and updates in a straightforward and safe way. We’ll first explain what the source-level inliner is and how you can use it, then we’ll dive into some aspects of the problem and the technology behind it.Source-level inlining Go to source-level-inlining
Source-level inlining
In 2023, we built an
algorithm
for source-level inlining of function calls in Go. To “inline” a call means to replace the call by a copy of the body of the called function, substituting arguments for parameters. We call it “source-level” inlining because it durably modifies the source code. By contrast, the inlining algorithm found in a typical compiler, including Go’s, applies a similar transformation, but to the compiler’s ephemeral
intermediate representation
, to generate more efficient code.If you’ve ever invoked
gopls
’s “
Inline call
” interactive refactoring, you’ve used the source-level inliner. (In VS Code, this code action can be found on the “Source Action…” menu.) The before-and-after screenshots below show the effect of inlining the call to
sum
from the function named
six
.The inliner is a crucial building block for a number of source transformation tools. For example, gopls uses it for the “Change signature” and “Remove unused parameter” refactorings because, as we’ll see below, it takes care of many subtle correctness issues that arise when refactoring function calls.
This same inliner is also one of the analyzers in the all-new
go fix
command. In
go fix
, it enables self-service API migration and upgrades using a new
//go:fix inline
directive comment. Let’s take a look at a few examples of how this works and what it can be used for.Example: renaming ioutil.ReadFile Go to example-renaming-ioutilreadfile
Example: renaming
ioutil.ReadFileIn Go 1.16, the
ioutil.ReadFile
function, which reads the content of a file, was deprecated in favor of the new
os.ReadFile
function. In effect, the function was renamed, though of course Go’s
compatibility promise
prevents us from ever removing the old name.package ioutil
import "os"
// ReadFile reads the file named by filename…
// Deprecated: As of Go 1.16, this function simply calls [os.ReadFile].
func ReadFile(filename string) ([]byte, error) {
return os.ReadFile(filename)
}Ideally, we would like to change every Go program in the world to stop using
ioutil.ReadFile
and to call
os.ReadFile
instead. The inliner can help us do that. First we annotate the old function with
//go:fix inline
. This comment tells the tool that any time it sees a call to this function, it should inline the call.package ioutil
import "os"
// ReadFile reads the file named by filename…
// Deprecated: As of Go 1.16, this function simply calls [os.ReadFile].
//go:fix inline
func ReadFile(filename string) ([]byte, error) {
return os.ReadFile(filename)
}When we run
go fix
on a file containing a call to
ioutil.ReadFile
, it applies the replacement:$ go fix -diff ./...
-import "io/ioutil"
+import "os"- data, err := ioutil.ReadFile("hello.txt")
- data, err := os.ReadFile("hello.txt")
The call has been inlined, in effect replacing a call to one function by a call to another.
Because the inliner replaces a function call by a copy of the body of the called function, not by some arbitrary expression, in principle the transformation should not change the program’s behavior (barring code that inspects the call stack, of course). This differs from other tools that allow for arbitrary rewrites, such as
gofmt -r
, which are very powerful but need to be watched closely.For many years now, our Google colleagues on the teams supporting Java, Kotlin, and C++ have been using source-level inliner tools like this. To date, these tools have eliminated millions of calls to deprecated functions in Google’s code base. Users simply add the directives, and wait. During the night, robots quietly prepare, test, and submit batches of code changes across a monorepo of billions of lines of code. If all goes well, by the morning the old code is no longer in use and can be safely deleted. Go’s inliner is a relative newcomer, but it has already been used to prepare more than 18,000 changelists to Google’s monorepo.
Example: fixing API design flaws Go to example-fixing-api-design-flaws
Example: fixing API design flaws
With a little creativity, a variety of migrations can be expressed as inlinings. Consider this hypothetical
oldmath
package:// Package oldmath is the bad old math package.
package oldmath// Sub returns x - y.
func Sub(y, x int) int// Inf returns positive infinity.
func Inf() float64// Neg returns -x.
func Neg(x int) intIt has several design flaws: the
Sub
function declares its parameters in the wrong order; the
Inf
function implicitly prefers one of the two infinities; and the
Neg
function is redundant with
Sub
. Fortunately we have a
newmath
package that avoids these mistakes, and we’d like to get users to switch to it. The first step is to implement the old API in terms of the new package and to deprecate the old functions. Then we add inliner directives:// Package oldmath is the bad old math package.
package oldmathimport "newmath"
// Sub returns x - y.
// Deprecated: the parameter order is confusing.
//go:fix inline
func Sub(y, x int) int {
return newmath.Sub(x, y)
}// Inf returns positive infinity.
// Deprecated: there are two infinite values; be explicit.
//go:fix inline
func Inf() float64 {
return newmath.Inf(+1)
}// Neg returns -x.
// Deprecated: this function is unnecessary.
//go:fix inline
func Neg(x int) int {
return newmath.Sub(0, x)
}Now, when users of
oldmath
run the
go fix
command on their code, it will replace all calls to the old functions by their new counterparts. By the way, gopls has included
inline
in its analyzer suite for some time, so if your editor uses gopls, the moment you add the
//go:fix inline
directives you should start seeing a diagnostic at each call site, such as “call of
oldmath.Sub
should be inlined”, along with a suggested fix that inlines that particular call.For example, this old code:
import "oldmath"
var nine = oldmath.Sub(1, 10) // diagnostic: "call to oldmath.Sub should be inlined"
will be transformed to:
import "newmath"
var nine = newmath.Sub(10, 1)
Observe that after the fix, the arguments to
Sub
are in the logical order. This is progress! If you’re in luck, the inliner will succeed at removing every call to the functions in
oldmath
, perhaps allowing you to delete it as a dependency.The
inline
analyzer works on types and constants too. If our
oldmath
package had originally declared a data type for rational numbers and a constant for π, we could use the following forwarding declarations to migrate them to the
newmath
package while preserving the behavior of existing code:package oldmath
//go:fix inline
type Rational = newmath.Rational//go:fix inline
const Pi = newmath.PiEach time the
inline
analyzer encounters a reference to
oldmath.Rational
or
oldmath.Pi
, it will update them to refer instead to
newmath
.Under the hood of the inliner
Under the hood of the inliner
At a glance, source inlining seems straightforward: just replace the call with the body of the callee function, introduce variables for the function parameters, and bind the call arguments to those variables. But handling all of the complexities and corner cases correctly while producing acceptable results is no small technical challenge: the inliner is about 7,000 lines of dense, compiler-like logic. Let’s look at six aspects of the problem that make it so tricky.
1. Parameter elimination
- Parameter elimination
One of the inliner’s most important tasks is to attempt to replace each occurrence of a parameter in the callee by its corresponding argument from the call. In the simplest case, the argument is a trivial literal such as
0
or
""
, so the replacement is straightforward and the parameter can be eliminated.//go:fix inline
func show(prefix, item string) {
fmt.Println(prefix, item)
}show("", "hello")
fmt.Println("", "hello")
For less trivial literals such as
404
or
"go.dev"
, the replacement is equally straightforward, so long as the parameter appears in the callee at most once. But if it appears multiple times, it would be bad style to sprinkle copies of these magic values throughout the code as it would obscure the relationship between them; a later change to only one of them might create an inconsistency.In such cases the inliner must tread carefully and emit a more conservative result. Whenever one or more parameters cannot be completely substituted for any reason, the inliner inserts an explicit “parameter binding” declaration:
//go:fix inline
func printPair(before, x, y, after string) {
fmt.Println(before, x, after)
fmt.Println(before, y, after)
}printPair("[", "one", "two", "]")
// a “parameter binding” declaration
var before, after = "[", "]"
fmt.Println(before, "one", after)
fmt.Println(before, "two", after)2. Side effects
- Side effects
In Go, as in all imperative programming languages, calling a function may have the side effect of updating variables, which in turn may affect the behavior of other functions. Consider the call to
add
below:func add(x, y int) int { return y + x }
z = add(f(), g())
A trivial inlining of the call would replace
x
with
f()
and
y
with
g()
, with this result:z = g() + f()
But this result is incorrect because evaluation of
g()
now occurs before
f()
; if the two functions have side effects, those effects will now be observed in a different order and may affect the result of the expression. Of course, it is bad form to write code that relies on effect ordering among call arguments, but that doesn’t mean people don’t do it, and our tools have to get it right.So, the inliner must attempt to prove that
f()
and
g()
do not have side effects on each other. On success, it can safely proceed with the result above. Otherwise, it must fall back to an explicit parameter binding:var x = f()
z = g() + xWhen considering side effects, it’s not only the argument expressions that matter. Also significant is the order in which parameters are evaluated relative to other code in the callee. Consider this call to
add2
://go:fix inline
func add2(x, y int) int {
return x + other() + y
}add2(f(), g())
This time, parameters
x
and
y
are used in the same order they are declared, so the substitution
f() + other() + g()
won’t change the order of effects of
f()
and
g()
—but it will change the order of any effects of
other()
and
g()
. Furthermore, if the function body uses a parameter within a loop, substitution might change the cardinality of effects.The inliner uses a novel
hazard analysis
to model the order of effects in each callee function. Nonetheless, its ability to construct the necessary safety proofs is quite limited. For example, if the calls
f()
and
g()
are simple accessors, it would be perfectly safe to call them in either order. Indeed, an optimizing compiler might use its knowledge of the internals of
f
and
g
to safely reorder the two calls. But unlike a compiler, which generates object code that reflects the source at a specific moment, the purpose of the inliner is to make permanent changes to the source, so it can’t take advantage of ephemeral details. As an extreme example, consider this
start
function:func start() { /* TODO: implement */ }
An optimizing compiler is free to delete each call to
start()
because it has no effects today, but the inliner is not, because it may become important tomorrow.In short, the inliner may produce results that—to the informed eye of a project maintainer—are clearly too conservative. In such cases, the fixed code would benefit stylistically from a little manual cleanup.
3. “Fallible” constant expressions
- “Fallible” constant expressions
You might imagine (as I once did) that it would always be safe to replace a parameter variable by a constant argument of the same type. Surprisingly, this turns out not to be the case, because some checks previously done at run time would now happen—and fail—at compile time. Consider this call to the
index
function://go:fix inline
func index(s string, i int) byte {
return s[i]
}index("", 0)
A naive inliner might replace
s
with
""
and
i
with
0
, resulting in
""[0]
, but this is not actually a legal Go expression because this particular index is out of bounds for this particular string. Because the expression
""[0]
is composed of constants, it is evaluated at compile time, and a program that contains it will not even build. By contrast, the original program would fail only if execution reaches this call to
index
, which presumably in a working program it does not.Consequently, the inliner must keep track of all expressions and their operands that might become constant during parameter substitution, triggering additional compile-time checks. It builds a
constraint system
and attempts to solve it. Each unsatisfied constraint is resolved by adding an explicit binding for the constrained parameters.4. Shadowing
- Shadowing
Typical argument expressions contain one or more identifiers that refer to symbols (variables, functions, and so on) in the caller’s file. The inliner must make sure that each name in the argument expression would refer to the same symbol after parameter substitution; in other words, none of the caller’s names is
shadowed
in the callee. If this fails, the inliner must again insert parameter bindings, as in this example://go:fix inline
func f(val string) {
x := 123
fmt.Println(val, x)
}x := "hello"
f(x)x := "hello"
{
// another “parameter binding” declaration
// to read the caller's x before shadowing it
var val string = x
x := 123
fmt.Println(val, x)
}Conversely, the inliner must also check that each name in the
callee
function body would refer to the same thing when it is spliced into the call site. In other words, none of the callee’s names is shadowed or missing in the caller. For missing names, the inliner may need to insert additional imports.5. Unused variables
- Unused variables
When an argument expression has no effects and its corresponding parameter is never used, the expression may be eliminated. However, if the expression contains the last reference to a local variable at the caller, this may cause a compile error because the variable is now unused.
//go:fix inline
func f(_ int) { print("hello") }x := 42
f(x)x := 42 // error: unused variable: x
print("hello")So the inliner must account for references to local variables and avoid removing the last one. (Of course it is still possible that two different inliner fixes each remove the
second
-to-last reference to a variable, so the two fixes are valid in isolation but not together; see the discussion of
semantic conflicts
in the previous post. Unfortunately manual cleanup is inevitably required in this case.)6. Defer
- Defer
In some cases, it is simply impossible to inline away the call. Consider a call to a function that uses a
defer
statement: if we were to eliminate the call, the deferred function would execute when the
caller
function returns, which is too late. All we can safely do when the callee uses
defer
is to put the body of the callee in a function literal and immediately call it. This function literal,
func() { … }()
, delimits the lifetime of the
defer
statement, as in this example://go:fix inline
func callee() {
defer f()
…
}callee()
func() {
defer f()
…
}()If you invoke the inliner in gopls, you’ll see that it makes the change shown above and introduces the function literal. This result may be appropriate in an interactive setting, since you are likely to immediately tweak the code (or undo the fix) as you prefer, but it is rarely desirable in a batch tool, so as a matter of policy the analyzer in
go fix
refuses to inline such “literalized” calls.An optimizing compiler for tidiness
An optimizing compiler for “tidiness”
We’ve now seen half a dozen examples of how the inliner handles tricky semantic edge cases correctly. (Many thanks to Rob Findley, Jonathan Amsterdam, and Olena Synenka for insights, discussions, reviews, features, and fixes.) By putting all of the smarts into the inliner, users can simply apply an “Inline call” refactoring in their IDE or add a
//go:fix inline
directive to their own functions and be confident that the resulting code transformations can be applied with only the most cursory review.Although we have made good progress toward that goal, we have not yet fully attained it, and it is likely that we never will. Consider a compiler. A sound compiler produces correct output for any input and never miscompiles your code; this is the fundamental expectation that every user should have of their compiler. An
optimizing
compiler produces code carefully chosen for speed without compromising on safety. Similarly, an inliner is a bit like an optimizing compiler whose goal is not speed but
tidiness
: inlining a call must never change the behavior of your program, and ideally it produces code that is maximally neat and tidy. Unfortunately, an optimizing compiler is
provably
never done: showing that two different programs are equivalent is an undecidable problem, and there will always be improvements that an expert knows are safe but the compiler cannot prove. So too with the inliner: there will always be cases where the inliner’s output is too fussy or otherwise stylistically inferior to that of a human expert, and there will always be more “tidiness optimizations” to add.Try it out! Go to try-it-out
Try it out!
Try it out!
We hope this tour of the inliner gives you a sense of some of the challenges involved, and of our priorities and directions in providing sound, self-service code transformation tools. Please try out the inliner, either interactively in your IDE, or through
//go:fix inline
directives and the
go fix
command, and share with us your experiences and any ideas you have for further improvements or new tools.Previous article: Allocating on the Stack
Blog Index
Original source - March 2026
- No date parsed from source.
- First seen by Releasebot:Mar 6, 2026
[security] Go 1.26.1 and Go 1.25.8 are released
Go releases 1.26.1 and 1.25.8 bring five security fixes across crypto/x509, html/template, net/url and os. Highlights address certificate verification constraints, panics on malformed certs, meta tag URL escaping, IPv6 literal validation, and directory FileInfo root escapes. Includes download links.
Go releases: Go 1.26.1 and 1.25.8
Hello gophers,
We have just released Go versions 1.26.1 and 1.25.8, minor point releases.
These releases include 5 security fixes following the security policy:
crypto/x509: incorrect enforcement of email constraints
When verifying a certificate chain which contains a certificate containing
multiple email address constraints (composed of the full email address) which
share common local portions (the portion of the address before the '@'
character) but different domain portions (the portion of the address after the
'@' character), these constraints will not be properly applied, and only the
last constraint will be considered.This can allow certificates in the chain containing email addresses which are
either not permitted or excluded by the relevant constraints to be returned by
calls to Certificate.Verify. Since the name constraint checks happen after chain
building is complete, this only applies to certificate chains which chain to
trusted roots (root certificates either in VerifyOptions.Roots or in the system
root certificate pool), requiring a trusted CA to issue certificates containing
either not permitted or excluded email addresses.This issue only affects Go 1.26.
Thanks to Jakub Ciolek for reporting this issue.
This is CVE-2026-27137 and Go issue https://go.dev/issue/77952.
crypto/x509: panic in name constraint checking for malformed certificates
Certificate verification can panic when a certificate in the chain has an empty
DNS name and another certificate in the chain has excluded name constraints.
This can crash programs that are either directly verifying X.509 certificate
chains, or those that use TLS.Since the name constraint checks happen after chain building is complete, this
only applies to certificate chains which chain to trusted roots (root
certificates either in VerifyOptions.Roots or in the system root certificate
pool), requiring a trusted CA to issue certificates containing malformed DNS
names.This issue only affects Go 1.26.
Thanks to Jakub Ciolek for reporting this issue.
This is CVE-2026-27138 and Go issue https://go.dev/issue/77953.
html/template: URLs in meta content attribute actions are not escaped
Actions which insert URLs into the content attribute of HTML meta tags are not
escaped. This can allow XSS if the meta tag also has an http-equiv attribute
with the value "refresh".A new GODEBUG setting has been added, htmlmetacontenturlescape, which can be
used to disable escaping URLs in actions in the meta content attribute which
follow "url=" by setting htmlmetacontenturlescape=0.This is CVE-2026-27142 and Go issue https://go.dev/issue/77954.
net/url: reject IPv6 literal not at start of host
The Go standard library function net/url.Parse insufficiently
validated the host/authority component and accepted some invalid URLs
by effectively treating garbage before an IP-literal as ignorable.
The function should have rejected this as invalid.To prevent this behavior, net/url.Parse now rejects IPv6 literals
that do not appear at the start of the host subcomponent of a URL.Thanks to Masaki Hara (https://github.com/qnighy) of Wantedly.
This is CVE-2026-25679 and Go issue https://go.dev/issue/77578.
os: FileInfo can escape from a Root
On Unix platforms, when listing the contents of a directory using
File.ReadDir or File.Readdir the returned FileInfo could reference
a file outside of the Root in which the File was opened.The contents of the FileInfo were populated using the lstat system
call, which takes the path to the file as a parameter. If a component
of the full path of the file described by the FileInfo is replaced with
a symbolic link, the target of the lstat can be directed to another
location on the filesystem.The impact of this escape is limited to reading metadata provided by
lstat from arbitrary locations on the filesystem. This could be used
to probe for the presence or absence of files as well as gleaning
metadata like file sizes, but does not permit reading or writing files
outside the root.The FileInfo is now populated using fstatat.
Thank you to Miloslav Trmač of Red Hat for reporting this issue.
This is CVE-2026-27139 and Go issue https://go.dev/issue/77827.
View the release notes for more information:
https://go.dev/doc/devel/release#go1.26.1You can download binary and source distributions from the Go website:
https://go.dev/dl/To compile from source using a Git clone, update to the release with
git checkout go1.26.1
and build as usual.Thanks to everyone who contributed to the releases.
Cheers,
Original source
Cherry and David for the Go team - Feb 27, 2026
- Date parsed from source:Feb 27, 2026
- First seen by Releasebot:Feb 28, 2026
Allocating on the Stack
Go 1.26 brings automatic stack-allocated backing stores for small slices, dramatically reducing heap allocations and GC work. The article traces progress from 1.24/1.25 and shows the compiler now moves escaping slices to the heap only when needed, boosting speed and memory efficiency.
Keith Randall
27 February 2026We’re always looking for ways to make Go programs faster. In the last 2 releases, we have concentrated on mitigating a particular source of slowness, heap allocations. Each time a Go program allocates memory from the heap, there’s a fairly large chunk of code that needs to run to satisfy that allocation. In addition, heap allocations present additional load on the garbage collector. Even with recent enhancements like Green Tea, the garbage collector still incurs substantial overhead.
So we’ve been working on ways to do more allocations on the stack instead of the heap. Stack allocations are considerably cheaper to perform (sometimes completely free). Moreover, they present no load to the garbage collector, as stack allocations can be collected automatically together with the stack frame itself. Stack allocations also enable prompt reuse, which is very cache friendly.
Stack allocation of constant-sized slices Go to stack-allocation-of-constant-sized-slices
Stack allocation of constant-sized slices¶
Consider the task of building a slice of tasks to process:
func process(c chan task) { var tasks []task for t := range c { tasks = append(tasks, t) } processAll(tasks) }Let’s walk through what happens at runtime when pulling tasks from the channel
c
and adding them to the slice
tasks
.
On the first loop iteration, there is no backing store for
tasks
, so
append
has to allocate one. Because it doesn’t know how big the slice will eventually be, it can’t be too aggressive. Currently, it allocates a backing store of size 1.
On the second loop iteration, the backing store now exists, but it is full.
append
again has to allocate a new backing store, this time of size 2. The old backing store of size 1 is now garbage.
On the third loop iteration, the backing store of size 2 is full.
append
again has to allocate a new backing store, this time of size 4. The old backing store of size 2 is now garbage.
On the fourth loop iteration, the backing store of size 4 has only 3 items in it.
append
can just place the item in the existing backing store and bump up the slice length. Yay! No call to the allocator for this iteration.
On the fifth loop iteration, the backing store of size 4 is full, and
append
again has to allocate a new backing store, this time of size 8.
And so on. We generally double the size of the allocation each time it fills up, so we can eventually append most new tasks to the slice without allocation. But there is a fair amount of overhead in the “startup” phase when the slice is small. During this startup phase we spend a lot of time in the allocator, and produce a bunch of garbage, which seems pretty wasteful. And it may be that in your program, the slice never really gets large. This startup phase may be all you ever encounter.
If this code was a really hot part of your program, you might be tempted to start the slice out at a larger size, to avoid all of these allocations.func process2(c chan task) { tasks := make([]task, 0, 10) // probably at most 10 tasks for t := range c { tasks = append(tasks, t) } processAll(tasks) }This is a reasonable optimization to do. It is never incorrect; your program still runs correctly. If the guess is too small, you get allocations from
append
as before. If the guess is too large, you waste some memory.
If your guess for the number of tasks was a good one, then there’s only one allocation site in this program. The
make
call allocates a slice backing store of the correct size, and
append
never has to do any reallocation.
The surprising thing is that if you benchmark this code with 10 elements in the channel, you’ll see that you didn’t reduce the number of allocations to 1, you reduced the number of allocations to 0!
The reason is that the compiler decided to allocate the backing store on the stack. Because it knows what size it needs to be (10 times the size of a task) it can allocate storage for it in the stack frame of
process2
instead of on the heap1. Note that this depends on the fact that the backing store does not escape to the heap inside of
processAll
.### Stack allocation of variable-sized slices Go to stack-allocation-of-variable-sized-slices Stack allocation of variable-sized slices¶ But of course, hard coding a size guess is a bit rigid. Maybe we can pass in an estimated length? ```go func process3(c chan task, lengthGuess int) { tasks := make([]task, 0, lengthGuess) for t := range c { tasks = append(tasks, t) } processAll(tasks) }This lets the caller pick a good size for the
tasks
slice, which may vary depending on where this code is being called from.
Unfortunately, in Go 1.24 the non-constant size of the backing store means the compiler can no longer allocate the backing store on the stack. It will end up on the heap, converting our 0-allocation code to 1-allocation code. Still better than having
append
do all the intermediate allocations, but unfortunate.
But never fear, Go 1.25 is here!
Imagine you decide to do the following, to get the stack allocation only in cases where the guess is small:func process4(c chan task, lengthGuess int) { var tasks []task if lengthGuess <= 10 { tasks = make([]task, 0, 10) } else { tasks = make([]task, 0, lengthGuess) } for t := range c { tasks = append(tasks, t) } processAll(tasks) }Kind of ugly, but it would work. When the guess is small, you use a constant size
make
and thus a stack-allocated backing store, and when the guess is larger you use a variable size
make
and allocate the backing store from the heap.
But in Go 1.25, you don’t need to head down this ugly road. The Go 1.25 compiler does this transformation for you! For certain slice allocation locations, the compiler automatically allocates a small (currently 32-byte) slice backing store, and uses that backing store for the result of the
make
if the size requested is small enough. Otherwise, it uses a heap allocation as normal.
In Go 1.25,
process3
performs zero heap allocations, if
lengthGuess
is small enough that a slice of that length fits into 32 bytes. (And of course that
lengthGuess
is a correct guess for how many items are in
c
.)
We’re always improving the performance of Go, so upgrade to the latest Go release and be surprised by how much faster and memory efficient your program becomes!### Stack allocation of append-allocated slices Go to stack-allocation-of-append-allocated-slices Stack allocation of append-allocated slices¶ Ok, but you still don’t want to have to change your API to add this weird length guess. Anything else you could do? Upgrade to Go 1.26! ```go func process(c chan task) { var tasks []task for t := range c { tasks = append(tasks, t) } processAll(tasks) }In Go 1.26, we allocate the same kind of small, speculative backing store on the stack, but now we can use it directly at the
append
site.
On the first loop iteration, there is no backing store for
tasks
, so
append
uses a small, stack-allocated backing store as the first allocation. If, for instance, we can fit 4
task
s in that backing store, the first
append
allocates a backing store of length 4 from the stack.
The next 3 loop iterations append directly to the stack backing store, requiring no allocation.
On the 4th iteration, the stack backing store is finally full and we have to go to the heap for more backing store. But we have avoided almost all of the startup overhead described earlier in this article. No heap allocations of size, 1, 2, and 4, and none of the garbage that they eventually become. If your slices are small, maybe you will never have a heap allocation.### Stack allocation of append-allocated escaping slices Go to stack-allocation-of-append-allocated-escaping-slices Stack allocation of append-allocated escaping slices¶ Ok, this is all good when the tasks slice doesn’t escape. But what if I’m returning the slice? Then it can’t be allocated on the stack, right? Right! The backing store for the slice returned by extract below can’t be allocated on the stack, because the stack frame for extract disappears when extract returns. ```go func extract(c chan task) []task { var tasks []task for t := range c { tasks = append(tasks, t) } return tasks }But you might think, the
returned
slice can’t be allocated on the stack. But what about all those intermediate slices that just become garbage? Maybe we can allocate those on the stack?func extract2(c chan task) []task { var tasks []task for t := range c { tasks = append(tasks, t) } tasks2 := make([]task, len(tasks)) copy(tasks2, tasks) return tasks2 }Then the
tasks
slice never escapes
extract2
. It can benefit from all of the optimizations described above. Then at the very end of
extract2
, when we know the final size of the slice, we do one heap allocation of the required size, copy our
task
s into it, and return the copy.
But do you really want to write all that additional code? It seems error prone. Maybe the compiler can do this transformation for us?
In Go 1.26, it can!
For escaping slices, the compiler will transform the original
extract
code to something like this:func extract3(c chan task) []task { var tasks []task for t := range c { tasks = append(tasks, t) } tasks = runtime.move2heap(tasks) return tasks }runtime.move2heap
is a special compiler+runtime function that is the identity function for slices that are already allocated in the heap. For slices that are on the stack, it allocates a new slice on the heap, copies the stack-allocated slice to the heap copy, and returns the heap copy.
This ensures that for our original
extract
code, if the number of items fits in our small stack-allocated buffer, we perform exactly 1 allocation of exactly the right size. If the number of items exceeds the capacity our small stack-allocated buffer, we do our normal doubling-allocation once the stack-allocated buffer overflows.
The optimization that Go 1.26 does is actually better than the hand-optimized code, because it does not require the extra allocation+copy that the hand-optimized code always does at the end. It requires the allocation+copy only in the case that we’ve exclusively operated on a stack-backed slice up to the return point.
We do pay the cost for a copy, but that cost is almost completely offset by the copies in the startup phase that we no longer have to do. (In fact, the new scheme at worst has to copy one more element than the old scheme.)
Original source### Wrapping up Wrapping up¶ Hand optimization can still be beneficial, especially if you have a good estimate of the slice size ahead of time. But hopefully the compiler will now catch a lot of the simple cases for you and allow you to focus on the remaining ones that really matter. There are a lot of details that the compiler needs to ensure to get all these optimizations right. If you think that one of these optimizations is causing correctness or (negative) performance issues for you, you can turn them off with -gcflags=all=-d=variablemakehash=n . If turning these optimizations off helps, please file an issue so we can investigate. ### Footnotes Go to footnotes Footnotes¶ 1 Go stacks do not have any alloca -style mechanism for dynamically-sized stack frames. All Go stack frames are constant sized.
Curated by the Releasebot team
Releasebot is an aggregator of official product update announcements from hundreds of software vendors and thousands of sources.
Our editorial process involves the manual review and audit of release notes procured with the help of automated systems.