🎉 Welcome to the v2.5.0-beta.2 release of the kgateway project!
Release Notes
Changes since v2.5.0-beta.1
Breaking Changes
-
Envoy HTTP connection manager and TCP proxy stats are now reported per listener.
stat_prefixfollows a stable format:http_<port>for HTTP listeners,https_<port>_<listener>for HTTPS listeners (https_<port>_<namespace>_<listenerset>_<listener>for ListenerSet listeners), andtcp_<port>_<namespace>_<route>/tls_<port>_<namespace>_<route>for TCPRoutes and TLSRoutes. Previously every HTTP and HTTPS listener sharedstat_prefix: http, and TCPRoute/TLSRoute prefixes contained dots that split them across metric names.Action required if you consume Envoy stats: queries that match
envoy_http_conn_manager_prefix="http"or the old per-routeenvoy_tcp_*metric names, andGatewayParametersstats.matcherentries that match raw stat names such ashttp.http., must be updated. Aggregations that ignore these labels are unaffected. Gateways with many HTTPS listeners or ListenerSets will expose more HCM series, one set per listener.
(#14753) -
Removed the
kgateway_translator_translations_runningandkgateway_controller_reconciliations_runninggauges, and thetranslator="TranslateHTTPRoute"series ofkgateway_translator_translations_totalandkgateway_translator_translation_duration_seconds. Recording these series on every route of every Gateway translation cost significant CPU at scale. (#14812) -
Removed the
kgateway_status_syncer_status_syncs_totalandkgateway_status_syncer_status_sync_duration_secondsmetrics. Usekgateway_resources_status_sync_duration_secondsfor status latency andkgateway_resources_status_syncs_started_totalminuskgateway_resources_status_syncs_completed_totalfor resources whose status is out of sync. For code built on kgateway:statussync.RecordStatusSync,statussync.RecordStatusSyncOutcome,statussync.SyncMetricLabels,statussync.ConditionErrorandpluginutils.ConditionErrorMetricwere removed,RegisterPolicyStatusWithBuilderno longer takes aConditionErrorMetricargument, andstatussync.Writer.OnSyncno longer receives atime.Duration. Callstatussync.EndResourceStatusSyncOnWriteSuccessfromOnSyncinstead ofRecordStatusSyncOutcome. (#14829) -
Removed the
kgateway_resources_status_syncs_started_total,kgateway_resources_status_syncs_completed_totalandkgateway_resources_status_sync_duration_secondsmetrics. Addedkgateway_status_writes_total{kind, result}, which counts status writes by result (written,unchanged,conflict,not_found,error); alert onresult="error"to catch status writes that failed after every retry. For code built on kgateway:statussync.Writer.OnSync,statussync.EndResourceStatusSyncOnWriteSuccess,metrics.StartResourceStatusSyncandmetrics.EndResourceStatusSyncwere removed. (#14838) -
Changing a Gateway or ListenerSet listener port no longer restarts the proxy pods.
Listener ports are no longer listed as container ports on the proxy Deployment.
If you reference the proxy pods' named ports (listener-<port>) from your own Services, switch to port numbers before upgrading. If you run the proxy with hostNetwork, add the ports back with a deploymentOverlay.
(#14866)
New Features
- Add
percentEnabled/percentEnforcedfields to theRateLimitProviderGatewayExtension, enabling shadow mode for global rate limiting (call the rate limit service without enforcing its decision) via Envoy'sfilter_enabled/filter_enforcedruntime settings. (#14583) - BackendTLSPolicy now supports the kgateway.dev/* TLS extension options (cipher-suites, ecdh-curves, signature-algorithms, min-tls-version, max-tls-version, verify-subject-alt-names, verify-certificate-hash) through its options field, matching what is already supported on Gateway listener TLS config. (#14731)
- Support HTTP CONNECT proxy tunneling configuration (#14794)
- Route changes are now batched before Gateway translation, so a burst of route updates rebuilds each affected Gateway once per batch instead of once per route. This sharply reduces controller CPU and memory churn at route scale, and delays each route change by tens of milliseconds. Tune with
KGW_TRANSLATION_DEBOUNCE(default10ms) andKGW_TRANSLATION_DEBOUNCE_MAX(default100ms), or setKGW_TRANSLATION_DEBOUNCE=0to disable batching. (#14813) - Added the
kgateway_build_infometric, which reports the controller's version, git revision, Go version, OS and architecture as labels on a gauge with value 1. (#14851)
Bug Fixes
- Fix route validation after RouteConfiguration plugins and extend strict validation to include final virtual-host and shared route-configuration settings, isolating invalid configuration with scoped fallbacks. (#14324)
- fix: a backendRef naming an existing resource with a port it does not define now reports "found, but port N not defined" on ResolvedRefs, instead of claiming the resource was not found (#14706)
- Policies whose targetRefs name a Gateway, ListenerSet, HTTPRoute, GRPCRoute, Service, or Backend that does not exist now report
Accepted: Falsewith reasonTargetNotFoundon a syntheticStatusSummaryancestor entry, listing the unresolved targets. (#14709) - AWS Lambda backends now send the Lambda endpoint as the Host header, matching the AWS SDKs, instead of forwarding the client's authority. This takes precedence over route-level URLRewrite hostname and TrafficPolicy.autoHostRewrite settings. (#14712)
- Fix the gateway deployer dropping the
appArmorProfile,seLinuxChangePolicyandsupplementalGroupsPolicysecurity context fields when merging GatewayParameters overrides. (#14725) - Add opt-in
spec.kube.envoyContainer.bootstrap.maxDownstreamConnectionson GatewayParameters to configure Envoy's global downstream connection limit. No limit is set by default. (#14727) - Fixed delegated child HTTPRoutes getting no status when their HTTPRoute parentRef omits the namespace. (#14758)
- fix: The status of a TrafficPolicy now names the failing GatewayExtension, and OpenID discovery failures name the discovery URL with any password masked (#14769)
- Fixed endpoints without a locality receiving no traffic when other endpoints of the same backend have a locality. (#14775)
- Gateway listener TLS options and BackendTLSPolicy options now ignore keys outside the kgateway.dev/ prefix instead of rejecting them. Unknown kgateway.dev/* keys are still reported as errors. (#14782)
- fix: redirect path now accept query strings and other targets that Envoy itself permits, instead of being validated against the stricter rules meant for match paths only (#14791)
- Fixed strict validation rejecting local rate limits with
shareAcrossGateway: true. (#14793) - Fixed
PreferNetworkand other network-aware traffic distribution splitting traffic across networks when the gateway or backend pods have notopology.istio.io/networklabel. A pod or WorkloadEntry without a network now inherits thetopology.istio.io/networklabel of the Istio system namespace. (#14796) - AWS Backend Secrets whose accessKey, secretKey or sessionToken have leading or trailing whitespace are now rejected at translation and reported on the Backend's Accepted condition, instead of producing a malformed SigV4 Authorization header and a 403 from AWS. (#14804)
- Fixed frontend TLS client certificate validation rejecting
caCertificateRefsthat setgroup: core; these are now treated the same asgroup: "". (#14807) - Fixed redundant route and policy status writes when other controllers report status on the same resource and reorder
status.parentsorstatus.ancestors. (#14810) - Populate message on Gateway Programmed condition when no valid listeners exist. (#14841)
- Callbacks set with
WithExtraXDSCallbacksnow receive every xDS server hook, including stream open, responses, and delta hooks; before, only stream requests, stream close, and fetch requests reached them.krtcollections.NewUniquelyConnectedClientsno longer takes extra callbacks: chain them with the newsetup.ChainCallbacks. (#14856) - Fixed a controller panic when a TrafficPolicy with a buffer was compared with one without, such as after a policy weight change. (#14860)
- Fixed endpoint and route updates stopping for every gateway proxy that received a cluster or listener Envoy rejected. The updates stayed stopped after the resource was removed, and proxies started meanwhile served 503 with empty clusters. (#14865)
Cleanup
- Per-client ClusterLoadAssignments that resolve identically are now shared in memory across clients. Every EDS resource version string changes once when the upgraded control plane starts, so each connected Envoy receives one EDS push with identical content on upgrade. (#14604)
- Reduce per-client CDS memory and fleet-churn work by sharing immutable backend clusters. (#14692)
- Share inline endpoint assignments across clients when locality and endpoint policies cannot change them. (#14693)
- Avoid per-client inline endpoint rebuilding for backends whose hosts have no DestinationRule. (#14694)
- Reduce repeated strict-mode backend validation work by caching verdicts by cluster content. (#14695)
Dependency Updates
- Upgrade OpenTelemetry Go dependencies to address CVE-2026-81870. (#14764)
- bump envoy to v1.39.4 (#14827)
Contributors
Thanks to all the contributors who made this release possible:
Installation
The kgateway project is available as a Helm chart and docker images.
Helm Charts
The Helm charts are available at:
- oci://cr.kgateway.dev/kgateway-dev/charts/kgateway
- oci://cr.kgateway.dev/kgateway-dev/charts/kgateway-crds
Docker Images
The docker images are available at:
- cr.kgateway.dev/kgateway-dev/kgateway:v2.5.0-beta.2
- cr.kgateway.dev/kgateway-dev/sds:v2.5.0-beta.2
- cr.kgateway.dev/kgateway-dev/envoy-wrapper:v2.5.0-beta.2
Quickstart
Try installing this release:
helm install kgateway-crds oci://cr.kgateway.dev/kgateway-dev/charts/kgateway-crds --version v2.5.0-beta.2 --namespace kgateway-system --create-namespace
helm install kgateway oci://cr.kgateway.dev/kgateway-dev/charts/kgateway --version v2.5.0-beta.2 --namespace kgateway-system --create-namespace
For detailed installation instructions and next steps, please visit our quickstart guide.















