Announcing Envoy Gateway v1.9

Envoy Gateway v1.9 release announcement.

We are excited to announce the release of Envoy Gateway v1.9.0.

This release delivers new capabilities across traffic management, security, extensibility, observability, and infrastructure — along with key bug fixes and performance improvements. We extend our thanks to the entire Envoy Gateway community for your ongoing contributions, feedback, and collaboration. Your efforts make each release possible.

Release NotesDocsCompatibility MatrixInstall

What’s New

Envoy Gateway v1.9.0 introduces powerful enhancements, resolves critical issues, and continues to improve the platform’s reliability and performance.


🚨 Breaking Changes

  • ClientTrafficPolicy.spec.clientIPDetection now requires exactly one of xForwardedFor, customHeader, or directSourceIP to be set. Previously an empty clientIPDetection: {} was accepted; it is now rejected by CEL validation.
  • Moved the Gateway API safe-upgrades ValidatingAdmissionPolicy resources out of the CRD bundle and into the gateway-helm chart templates so tools such as Flux no longer treat them as CRDs. During upgrades, two upgrade cases require action: (1) if you install Gateway API CRDs separately (e.g. with the gateway-crds-helm chart and helm install --skip-crds), the safe-upgrades ValidatingAdmissionPolicy and its binding are now rendered by the gateway-helm chart, so add Helm ownership metadata (the meta.helm.sh/release-name, meta.helm.sh/release-namespace annotations and the app.kubernetes.io/managed-by=Helm label) to the ValidatingAdmissionPolicy/safe-upgrades.gateway.networking.k8s.io and ValidatingAdmissionPolicyBinding/safe-upgrades.gateway.networking.k8s.io resources before upgrading so Helm can manage them (see https://gateway.envoyproxy.io/v1.8/install/install-helm/#installing-crds-separately); (2) if Gateway API CRDs and safe upgrade policy resources are managed by your cloud provider (or any other mechanism outside this chart), note that --skip-crds does not skip chart-templated resources, so disable rendering of the safe-upgrades ValidatingAdmissionPolicy by setting crds.gatewayAPI.safeUpgradePolicy.enabled=false (see https://gateway.envoyproxy.io/v1.8/install/install-helm/#clusters-with-compatible-provider-managed-gateway-api-crds).
  • The SDS (Secret Discovery Service) reference secret url field must now include the unix:// scheme (e.g. unix:///var/run/secrets/workload-spiffe-uds/socket). Bare filesystem paths that were previously accepted (introduced in v1.9.0-rc.0) are now rejected and must be updated.
  • Lua EnvoyExtensionPolicies are now disabled by default. Use the new enableLua field in extensionApis to explicitly enable them. The disableLua field is deprecated and will be removed in a future release.
  • JWT authentication provider and requirement names in generated listener xDS now use stable, content-derived names so identical providers can be deduplicated across routes. EnvoyPatchPolicy or extension-server integrations that match previous route-derived jwt_authn.providers or requirementMap keys must update those references.
  • DNS-based clusters are now generated using Envoy’s envoy.cluster.dns cluster extension (envoy.extensions.clusters.dns.v3.DnsCluster) instead of the deprecated dns_refresh_rate and respect_dns_ttl fields on the Envoy Cluster. DNS resolution behavior is unchanged, but EnvoyPatchPolicy and extension server implementations that read or patch type, dns_refresh_rate, respect_dns_ttl, or dns_lookup_family on these clusters must be updated to target the cluster_type (envoy.cluster.dns) typed config instead, since Envoy now sources these settings from the DnsCluster extension (and ignores the top-level Cluster.dns_lookup_family when cluster_type is set).
  • EndpointSlice field indexing is now enabled by default by the EndpointSliceIndex runtime flag and can increase Envoy Gateway controller memory usage in clusters with many EndpointSlices. Before upgrading, especially in production, operators should review and, if needed, increase the Envoy Gateway pod memory requests/limits, or opt out by adding EndpointSliceIndex to runtimeFlags.disabled.
  • The XRateLimitHeadersOptionDisabled constant in BackendTrafficPolicy now correctly holds the value "Off" to match the CRD enum (previously "Disabled"). Since "Disabled" was never a valid CRD enum value and would have been rejected by the API server, no existing manifests are affected.
  • The SessionPersistence.IdleTimeout field has been removed from the Gateway API HTTPRoute spec in v1.6. Envoy Gateway no longer validates or rejects routes that previously set this field; any existing manifests referencing sessionPersistence.idleTimeout must remove the field before upgrading the Gateway API CRDs to v1.6.
  • Envoy Gateway now reconciles TCPRoute/UDPRoute via the gateway.networking.k8s.io/v1 API. You must upgrade the Gateway API CRDs to v1.6 with this release. Existing v1alpha2 manifests continue to work (both versions are served), but if the v1.6 CRDs are not installed, TCP/UDP routes will be silently skipped. The stored version moves to v1; a storage-version migration will be required before v1alpha2 is eventually removed.
  • SecurityPolicy spec.apiKeyAuth.extractFrom admission validation is now stricter: the list must contain at least one entry, each entry must specify exactly one of headers, params, or cookies, and source names must be non-empty. SecurityPolicies that previously applied with an empty or ambiguous extractFrom (which produced no usable API key sources) will now be rejected and must be corrected before upgrading.
  • SecurityPolicy spec.mergeType admission validation is now stricter: mergeType can only be used with xRoute targets (HTTPRoute, GRPCRoute, and TCPRoute) and is rejected on Gateway, Gateway listener, ListenerSet, and ListenerSet listener targets. Existing SecurityPolicies using mergeType with those parent-resource targets must remove mergeType before updating the objects after the CRD upgrade.
  • Shared-only global rate limit rules are now written into typedPerFilterConfig instead of route.rateLimits in the generated xDS configuration. EnvoyPatchPolicies or extension servers that target route.rateLimits for shared-only global rate limit rules will stop matching after upgrade and must be updated to target the new location.
  • All BackendTLSPolicy resources using WellKnownCACertificates: System and Backend resources using spec.tls.wellKnownCACertificates: System now share a single SDS secret named system_ca_certificates instead of one per-resource secret named <resource-name>/<namespace>-ca. EnvoyPatchPolicies or extension servers referencing the old per-resource secret names or the cluster’s validationContextSdsSecretConfig field must be updated accordingly. Patching system_ca_certificates is not supported; users requiring a custom CA bundle per backend should use CACertificateRefs instead of WellKnownCACertificates: System. Disruption to traffic during upgrade is possible, due to warming of new secrets. To opt out and restore the old per-resource secret behavior, enable the PerResourceSystemCASecret runtime flag.
  • Tracing client sampling now defaults to 0% instead of 100%, so Envoy Gateway no longer honors client-forced tracing unless users explicitly opt in by setting clientSamplingFraction.
  • BackendTrafficPolicy spec.mergeType admission validation is now stricter: mergeType can only be used with xRoute targets (HTTPRoute, GRPCRoute, TCPRoute, UDPRoute, and TLSRoute) and is rejected on Gateway, Gateway listener, ListenerSet, and ListenerSet listener targets. Existing BackendTrafficPolicies using mergeType with those parent-resource targets must remove mergeType before updating the objects after the CRD upgrade.
  • Moved EnvoyExtensionPolicy Lua source code from per-route LuaPerRoute overrides to listener-level Lua filters to avoid route-count-dependent memory growth. This changes generated xDS Lua filter names and configuration layout; EnvoyPatchPolicies and extension servers matching the previous envoy.filters.http.lua/<index> keys must be updated.
  • SDS clusters generated for Unix socket URLs now include a hash suffix in their xDS names to prevent collisions between distinct paths. EnvoyPatchPolicies or extension servers that match the previous path-derived cluster names must update those references.
  • Removed the obsolete envoy.restart_features.use_eds_cache_for_ads runtime guard from generated Envoy bootstrap configuration because Envoy now uses the replacement behavior by default.

🔒 Security Updates

  • Fixed xDS server authentication bypass in GatewayNamespaceMode, adding Unary Interceptor and validating SotW requests.
  • Hardened the gateway-helm chart: the Envoy Gateway controller container now runs with a read-only root filesystem, and the certgen Job runs with a restricted pod-level securityContext by default.
  • Bumped Go to 1.26.5, which includes security fixes to the crypto/tls and os packages.
  • Bumped Go to 1.26.6, which includes security fixes to the crypto/tls, encoding/asn1, encoding/xml, html/template, net/http, net/url, golang.org/x/net/idna and golang.org/x/net/dns/dnsmessage packages.

✨ New Features

API & Traffic Management

  • Added spec.clientIPDetection.xForwardedFor.disableXForwardedForAppend to ClientTrafficPolicy to disable Envoy’s automatic X-Forwarded-For append behavior when using XFF-based client IP detection.
  • Added ClientTrafficPolicy.spec.clientIPDetection.directSourceIP to opt the listener into using the downstream TCP connection source address as the client IP. This unlocks SecurityPolicy clientIPGeoLocations in L4-transparent topologies (e.g. AWS NLB with target-type: instance + externalTrafficPolicy: Local, Azure Standard Load Balancer).
  • Added support for HTTPRouteFilter PathRegex hostname rewrites, allowing the upstream Host header to be derived from regex captures on the request path.
  • Added a requestBody field to the HTTP active health checker in BackendTrafficPolicy, allowing a request body payload to be sent during HTTP health checking. The field requires the health check method to be POST or PUT.
  • Added support for ListenerSet as a targetRef kind in ClientTrafficPolicy, allowing client traffic settings to be applied to a named group of listeners without a gateway-wide policy.
  • Added a new host section under ClientTrafficPolicy’s headers with a stripTrailingHostDot field to normalize the Host/Authority header (trailing dot removal) without an EnvoyPatchPolicy.
  • Added rateLimit.backend.redis.urlRef to source the global rate limit Redis URL from a Kubernetes Secret, enabling GitOps flows where the Redis endpoint is provisioned by an external controller.
  • Added support for ListenerSet as a targetRef kind in SecurityPolicy.\
  • Add support for more client timeout settings. The settings are ConnectionInspectionTimeout, RequestHeadersReceivedTimeout and TLSHandshakeTimeout
  • Added support for matching on response headers in BackendTrafficPolicy responseOverride via the match.responseHeaders field.
  • Added support for referencing an Envoy Gateway HTTPRouteFilter from a GRPCRoute rule via an extensionRef filter, enabling URL rewrite (authority/host and regex :path), direct response, credential injection, and cookie-based matches for gRPC traffic.
  • Added support for ListenerSet as a targetRef kind in BackendTrafficPolicy.
  • Added support for ListenerSet as a targetRef kind in EnvoyExtensionPolicy.
  • Added loadBalancer.backendUtilization.outOfBand to BackendTrafficPolicy, enabling out-of-band ORCA load reporting. Envoy opens a server-streaming gRPC connection to each endpoint’s xds.service.orca.v3.OpenRcaService/StreamCoreMetrics and pulls load reports on a schedule, independent of request traffic. This supplements in-band ORCA metrics carried in response headers and trailers rather than replacing them — reports from either source feed the same endpoint weights. reportingPeriod controls how often reports are requested, while port and authority allow reaching a dedicated reporting sidecar. The backend must implement OpenRcaService for this to take effect.
  • Added support for MergeType in EnvoyExtensionPolicy to enable route-level policies to merge with parent Gateway, ListenerSet policies.
  • Added a Week unit to BackendTrafficPolicy’s global and local rate limiting, allowing rate limits to be expressed on a weekly basis in addition to Second/Minute/Hour/Day/Month/Year.

Security & Authentication

  • Added csrf field to SecurityPolicy for native Cross-Site Request Forgery protection, validating the Origin header of mutating requests against the destination and any additionalOrigins, with gradual rollout via shadowFraction.
  • Added support for CEL expressions in SecurityPolicy authorization rules.
  • Added support for authorization path match.
  • Added the autoSNIFromEndpointHostname TLS setting to Backends, allowing the SNI value sent to the backend to be automatically derived from the backend endpoint hostname instead of using a fixed SNI value.
  • Added support for SNI based dynamic forward proxy by allowing a Backend of type DynamicResolver to be referenced by a TLSRoute. The upstream host is resolved from the TLS SNI of the incoming connection.
  • Added allowExpiredCertificate to ClientTrafficPolicy tls.clientValidation, allowing operators to accept expired client certificates while still validating the CA chain and signature.
  • Added a failedRefetchDuration field to JWT providers in SecurityPolicy, configuring how long Envoy waits before re-fetching the JWKS after a failed fetch. If not specified, Envoy’s default of 1 second is used.
  • Added a failOpen field to JWT in SecurityPolicy, allowing a request to pass JWT authentication even when its JWT is missing or invalid (maps to Envoy’s allow_missing_or_failed). Verified claims are still forwarded, so it should be paired with an Authorization policy for enforcement.
  • Added spec.oidc.forwardIDToken to SecurityPolicy, allowing the OIDC ID token to be forwarded to the upstream on a configurable request header. When the header is Authorization, the ID token is forwarded using the Bearer prefix; for any other header the raw token value is set.
  • Added support for referencing a Secret of type gateway.envoyproxy.io/sds in a Gateway listener’s tls.certificateRefs, letting Envoy fetch the listener certificate from an external SDS server instead of an inline kubernetes.io/tls Secret, gated by the existing enableSDSSecretRef EnvoyGateway extension API flag. When multiple valid HTTPS listeners share a port, SDS-backed listeners default to HTTP/1.1 because their certificate DNS names are opaque; same-port listeners are also downgraded when their known certificate DNS names overlap the SDS listener hostname, or when that hostname is unspecified. Affected listeners report gateway.envoyproxy.io/TLSCertificateNamesUnknown=True with reason SDSCertificateOpaque.

Extensibility

  • Added support for filterContext field in Lua EnvoyExtensionPolicy, allowing shared Lua scripts to be parameterized per route via request_handle:filterContext().
  • Added a statusOnError field to the ExtProc settings in EnvoyExtensionPolicy, allowing the HTTP status returned to the client to be customized when the external processor is unreachable and failOpen is false.
  • Extension server policies can now target Resources in different namespaces using ReferenceGrant.
  • Extension server policies can now target HTTPRoutes, GRPCRoute, HTTPRoute rules (via sectionName) and GRPCRoute rules (via sectionName) in addition to Gateways and Gateway Listeners. The extension server attachment outcome is now reported in the policy’s status.ancestors.
  • Added xdsServer.maxReceiveMessageSize to the EnvoyGateway API and raised the xDS gRPC server’s default receive limit from 4MiB to 32MiB. At large resource counts, an Envoy proxy’s delta xDS request on stream reconnect can exceed 4MiB, which previously broke the stream with “received message larger than max” errors and left the proxy on its last known-good configuration.
  • Added EnvoyProxy.spec.mergeBackends to let routes referencing the identical backend share a single Envoy cluster instead of generating one cluster per route rule, reducing xDS size, active health-check traffic, and stats cardinality. Disabled by default and marked experimental.
  • Added a selector field to EnvoyProxy.spec.mergeBackends to restrict cluster deduplication to backends whose Service, ServiceImport, or Backend resource matches a label selector, so operators can opt individual backends in gradually instead of enabling deduplication for every backend at once.
  • Added healthCheckFailureDelay to ShutdownConfig, allowing Envoy Gateway to start graceful listener drain immediately while delaying health check failure during pod termination.

Infrastructure & Helm

  • Added a remote infrastructure provider. This allows users to define their own infrastructure management strategy.
  • Added startupProbe to the envoy-gateway Deployment with configurable liveness and readiness probes via Helm values.
  • Added support for disabling the crds dependency on the gateway-helm chart via crds.enabled variable.
  • Added support for deployment.envoyGateway.strategy in Helm values, allowing users to configure the Deployment update strategy (e.g. RollingUpdate or Recreate) for the Envoy Gateway control plane.
  • Added optional unhealthyPodEvictionPolicy field to envoy-gateway chart’s PodDisruptionBudget template.

Observability

  • Added a xdsNACKTotal metric to track the number of NACKs received from Envoy, labeled by node ID and resource type URL. A NACK is a DiscoveryRequest carrying an ErrorDetail, indicating that Envoy rejected the last config update. This metric can be used to alert on config issues causing xDS rejections.
  • Added a fromMetadata field to global rate limit limit in BackendTrafficPolicy, allowing the limit value to be sourced from per-request dynamic metadata (e.g. set by an upstream ext_proc), falling back to the static requests/unit when the metadata is absent.
  • Added support for setting the log level to off and critical for the Envoy Proxy.
  • Added support for configuring Envoy tracing client and overall sampling fractions on EnvoyProxy and BackendTrafficPolicy tracing settings.
  • Added support for health check event logging in EnvoyProxy and BackendTrafficPolicy.

Status & Validation

  • Added a RouteRulesOverlap warning status condition for routes whose match conditions are identical to another route on the same listener, so users can identify silently-shadowed routes.

🐞 Bug Fixes

  • Fixed Wasm extensions remaining permanently failed after transient errors fetching the Wasm module. Envoy’s built-in behavior only retried the fetch once after ~1 second and never re-attempted it, leaving the filter failed until the next configuration update. Envoy Gateway now configures the fetch with up to 10 retries using jittered exponential backoff (1s base interval, 30s max interval).
  • Fixed TLS secrets with non-canonical PEM formatting (e.g. unusual line endings) being passed verbatim to Envoy, which could cause BoringSSL errors such as BAD_END_LINE. Cert and key PEM data is now re-encoded to a canonical form before being delivered as xDS resources.
  • Fixed deduplicate CA certificates in ClientTrafficPolicy mTLS.
  • Fixed the xDS server in GatewayNamespaceMode serving a stale certificate after cert-manager rotation by re-reading the cert from disk on every TLS handshake.
  • Fixed controller panic when processing backend tls settings.
  • Fixed MaxStreamDuration not being set on CommonHttpProtocolOptions for non-route cluster.
  • Added validation for the SDS (Secret Discovery Service) cluster URI to ensure Unix Domain Socket (unix://) URLs are well-formed, rejecting a host component and requiring a path, instead of silently producing an invalid or unintended socket address.
  • Fixed API key auth credential ordering to avoid unnecessary xDS updates.
  • Fixed the CORS allowedOrigins validation pattern in SecurityPolicy rejecting valid origins that use non-HTTP schemes; the pattern now allows all RFC 3986 compliant URL schemes (e.g. moz-extension://example.com).
  • Fixed the EnvoyProxy resource not allowing IPv6 ranges in loadBalancerSourceRanges when configuring the envoy service.
  • Fixed egctl config commands hanging when Envoy pod port-forwarding fails.
  • Fixed Helm chart install/render failure when watch.namespaces is not set (default values) by wrapping the template check in a with block.
  • Fixed BackendTLSPolicy selection to prefer section name over wildcard match on the same backend.
  • Fixed missing deprecated field warning in ClientTrafficPolicy and SecurityPolicy.
  • Fixed ClientTrafficPolicy TLS cipher validation rejecting supported IANA/RFC cipher suite names.
  • Fixed Backend FQDN hostname validation to allow absolute domain names with a trailing dot.
  • Fixed egctl x status all/xroute/xpolicy failing when a Gateway API CRD (e.g. TCPRoute) is not installed in the cluster; missing CRDs are now skipped silently, or reported on stderr with -v.
  • Fixed Kubernetes provider namespace-scoped watches to always include the controller namespace so Envoy Gateway can read its own infrastructure resources.
  • Fixed HTTPRoute, GRPCRoute, TLSRoute, TCPRoute, and UDPRoute Accepted condition being set to False when an attached listener is not programmed due to a missing TLS certificate ref; listener programmed state is now correctly separated from route acceptance.
  • Fixed Kubernetes Service and ServiceImport appProtocol values kubernetes.io/ws and kubernetes.io/wss to force HTTP/1.1 upstream connections instead of negotiating HTTP/2, avoiding compatibility issues with WebSocket backends that do not support RFC 8441 extended CONNECT.
  • Fixed Backend TLS alpnProtocols: [] to disable upstream ALPN instead of inheriting EnvoyProxy BackendTLS defaults.
  • Fixed IPv6 literal hosts (e.g. [::1], [2001:db8::1]) not being detected in OIDC token/JWKS endpoints, which caused them to be built as STRICT_DNS clusters instead of static ones and bypassed the IP-literal check on the SecurityPolicy token endpoint.
  • Fixed the generated install.yaml creating a duplicate ValidatingAdmissionPolicy and its binding which caused kustomize build to fail with a duplicate resource error.
  • Fixed an ExternalName Service referenced as a route backend producing an invalid xDS cluster (with an empty address) that failed IR validation and stalled config delivery for the whole snapshot. ExternalName Services are now explicitly rejected as backends with a ResolvedRefs: False route condition; use an Envoy Gateway Backend resource with an FQDN endpoint instead.
  • Fixed ListenerSet hostname conflict resolution to apply listener precedence: Gateway-owned listeners win over ListenerSet listeners, and among ListenerSet listeners the first in processing order wins. Conflicted ListenerSet listeners now correctly report Accepted=False with the conflict reason. The Gateway’s AttachedListenerSets count now only reflects ListenerSets with at least one accepted listener.
  • Fixed ListenerSet protocol-conflict precedence so that Gateway-owned listeners collectively win when they share a single protocol, and only ListenerSet listeners using a different protocol are marked Conflicted/Accepted=False/Programmed=False. Previously, all listeners on a port could incorrectly be marked conflicted even when the Gateway itself had a clear protocol winner.
  • Fixed Gateway status reporting Programmed: False with reason AddressNotAssigned when the Envoy LoadBalancer service has no load balancer ingress (e.g. bare-metal clusters without a load balancer controller) but has addresses configured in spec.externalIPs, such as via an EnvoyProxy service patch. The external IPs are now used as a fallback for the Gateway status addresses.
  • Fixed EnvoyGateway config hot-reload to apply defaults before validation, so validators always run against a fully-defaulted struct on both the startup and reload paths.
  • Fixed an issue where, in GatewayNamespace mode, Envoy Gateway could take ownership of existing ServiceAccounts and ConfigMaps with colliding names; it now refuses to reconcile those resources unless they are already labeled as owned by the same Gateway.
  • Fixed ConsistentHash load balancer settings on non-route service clusters, such as SecurityPolicy extAuth backends, by emitting cluster-level HTTP hash policies.
  • Fixed upstream PROXY protocol clusters to preserve generated HTTP protocol options, including auto protocol detection for Backend TLS.
  • Fixed HTTPRoute per-retry timeout (derived from rule.timeouts.backendRequest) not being applied when no retry backoff was configured.
  • Fixed shared global rate limit rules with a cost field not working as expected.
  • Fixed BackendTrafficPolicy global rate limits rejecting requests: 0, allowing zero-request global rules to block matching traffic while local zero limits remain rejected.
  • Fixed the standalone offline controller used by the File provider to register the missing ListenerSet, ListenerSet-owned route, and ClusterTrustBundle EnvoyExtensionPolicy indexes so reconciliation no longer fails with unregistered index errors.
  • Fixed Gateway TLS Secret validation rejecting valid ECDSA private keys when the tls.key includes an EC PARAMETERS PEM block before the private key.
  • Fixed DaemonSet pod not using the configured custom ServiceAccount name.
  • Fixed redirect port leaking across multiple listeners when an HTTPRoute with a redirect filter (without explicit port) is attached to multiple Gateway listeners with different ports; each listener now correctly derives its own redirect port instead of reusing the first listener’s port.
  • Fixed cross-namespace targetSelectors for BackendTrafficPolicy RoutingType by using the target resource’s namespace in the index key instead of the policy’s namespace.
  • Fixed backend (upstream) TLS connections being capped at TLS 1.2 by default; they now default to a max of TLS 1.3 as documented.
  • Fixed a data race that could crash envoy-gateway with panic: reflect: slice index out of range when the watchable coalesce goroutine compared the xDS IR with reflect.DeepEqual while the translator concurrently mutated resource status in place; the translator now isolates status mutations by deep-copying only the status field of each resource at the start of translation.
  • Fixed TLS Secrets being pushed to Envoy and rejected by BoringSSL (KEY_VALUES_MISMATCH), which with mergeGateways enabled broke TLS for all Gateways sharing the proxy. A serving certificate chain that contains an expired (or malformed) certificate is now rejected during translation instead of having the expired member silently dropped (which corrupted the chain), and a Secret whose certificate and private key do not match is likewise rejected; both failures are isolated to the referencing listener. CA bundles used for client validation still drop expired CAs.
  • Fixed unreferenced Secret events triggering a full reconciliation whenever the HTTPRouteFilter CRD is installed. Every Secret write in the cluster previously enqueued a reconcile, causing sustained reconcile storms on clusters with high-frequency Secret writers (secret sync controllers, certificate rotation).
  • Fixed log timestamps regressing to Unix epoch floats (e.g. 1.784e+09) since v1.8.0 by explicitly setting ISO8601TimeEncoder on the production zap encoder config, restoring the expected ISO 8601 format (e.g. 2026-07-14T17:44:06.617Z).
  • Allow TLS v1.3 for remote JWKS fetching
  • Fixed initial fetch timed out for type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.Secret.
  • Fixed route and policy status never being written under high watch-event churn. When the informer cache lagged behind the API server, the status updater’s cache-backed Get could return NotFound for a freshly-created object and silently skip the status write, leaving the object with an empty status until a controller restart. The status updater now confirms a NotFound against an uncached reader before dropping the update.
  • Fixed a data race between config-reload and the standalone server’s shutdown/error logging by reading the logger through a new mutex-guarded Loader.Logger() accessor instead of the shared cfg.Logger field directly.
  • Fixed Envoy Gateway crash-looping at startup on clusters whose Gateway API CRD bundle omits ListenerSet, GRPCRoute or TLSRoute, such as GKE’s managed gateway-api-crds addon, by making those watches conditional on the CRD being present.
  • Fixed Envoy Gateway overriding the replica count computed by an HPA. The proxy and rate limit Deployments are applied with server-side apply using ForceOwnership, so rendering spec.replicas made envoy-gateway the owner of that field and every subsequent reconciliation reset the replica count to the statically configured value. The replicas field is now omitted from the generated Deployment when an HPA is configured (envoyHpa / rateLimitHpa), which is the behavior already documented for both. Use minReplicas to set a lower bound on the replica count instead.
  • Fixed NodePort Gateway Status.Addresses includes all nodes instead of only nodes with live Envoy pods when externalTrafficPolicy is Local.
  • Allow mixing IP and Unix Domain Socket endpoints in non-xRoute backends (ext-proc, ext-auth, etc.).
  • Fixed Envoy Gateway crash-looping at startup on clusters whose Gateway API CRD bundle omits BackendTLSPolicy, such as OpenShift’s Ingress-Operator-managed set, by making that watch conditional on the CRD being present. This completes the standard-channel guards added in #9583.
  • Fixed ListenerSet not being reconciled when a referenced TLS Secret is created or updated after the ListenerSet. Secret watches previously only indexed Gateway certificateRefs, so cert-manager style late Secret creation left the ListenerSet stuck with Programmed=False until an unrelated reconcile.
  • Fixed ConsistentHash load balancing not pinning a client to a single backend when a route splits traffic across multiple weighted backendRefs. Envoy Gateway now sets use_hash_policy on the generated weighted clusters when a ConsistentHash load balancer is configured, so the request’s hash policy selects the weighted cluster deterministically instead of at random per request.
  • Fixed mergeBackends incorrectly sharing or splitting clusters when a route’s parentRef omitted sectionName, by checking ClusterSettings merge-eligibility against each listener the route actually attaches to instead of the route’s literal sectionName.
  • Fixed SecurityPolicy rejecting OIDC cookieDomain values that contain a single-character label anywhere after the first label, such as example.m.com, because the validation pattern required every label but the first to be at least two characters. This applies to cookieDomain the same fix made for Backend FQDN endpoint hostnames in #4803.

🚀 Performance Improvements

  • Improved EndpointSlice lookup performance by using field indexes when processing backend references.
  • Reduced inotify watch usage for BackendTLSPolicy with WellKnownCACertificates: System by sharing a single SDS secret across all policies instead of creating one per policy.
  • Fixed translation latency growing quadratically when many policies share the same target by capping each policy’s status.ancestors at the CRD limit as ancestors are added, instead of only truncating during post-processing.

🛑 Deprecations

  • The disableLua field in extensionApis is deprecated in favor of enableLua.

📝 Other Changes

  • Refactored BackendTrafficPolicy merging to use the field-owner pattern already used for SecurityPolicy, resolving the response override body reference against the owning policy’s namespace instead of mutating the shared policy’s Spec before merge.
  • Increased the maximum number of header matches allowed in RateLimitSelectCondition.headers from 64 to 128.

📝 Upgrade Notes

  • We encourage all users to upgrade to v1.9.0 to take advantage of the new features, security improvements, and performance gains. For full details, see the Release Notes and updated Documentation.
  • Bumped the bundled Gateway API CRDs to v1.6.1. Envoy Gateway now reconciles TCPRoute/UDPRoute via gateway.networking.k8s.io/v1, so the updated Gateway API CRDs must be installed before upgrading.
  • For upgrade instructions, see Helm or YAML.