Istio 1.31.0 Change Notes
Istio 1.31.0 release notes.
Traffic Management
Improved logging when a Gateway API CRD installed in the cluster is below the minimum version required by this Istio version. The message is now logged at
warnlevel and explains that resources of that kind will not be processed until the CRDs are upgraded. Previously, this was logged atinfolevel and easy to miss, which made TLS passthrough breakage after upgrading to 1.30 with stale CRDs hard to diagnose.Improved istiod scalability in ambient mode by scoping XDS pushes from workload/service
Addresschanges to only the affected waypoints, instead of pushing to all waypoints and proxies. Can be disabled withAMBIENT_SCOPED_ADDRESS_PUSHES=false.Added support for a custom taint name for the pilot node untaint controller via the
PILOT_NODE_UNTAINT_CONTROLLERS_TAINT_NAMEenvironment variable. Defaults tocni.istio.io/not-ready. (Issue #57844)Added support for excluding policy configuration from Istio when the
istio.io/ignore-policy-attachmentannotation is set totrueon aBackendTLSPolicyorXBackendTrafficPolicyobject. This allows users to prevent specific policies from being translated into Istio configuration when the policy is intended for a different gateway controller than Istio.Example usage:
apiVersion: gateway.networking.k8s.io/v1
kind: BackendTLSPolicy
metadata:
annotations:
istio.io/ignore-policy-attachment: "true"Added support for excluding namespaces and hosts from a
Sidecaregress listener’shostsusing a~prefix on the namespace. Entries without a prefix are imported as before, and~-prefixed entries subtract from them:~ns1/*excludes all hosts inns1, and~/foo.comexcludesfoo.comfrom every namespace. This lets large meshes import everything except a few namespaces (e.g.*/*plus~ns1/*) without enumerating a long allowlist. (Issue #60139)Added an initialization check that verifies the bundled
nftbinary supports JSON output. The native nftables backend requires JSON to read configuration during pod removal. On hosts whosenftbinary doesn’t support JSON, those calls fail withError: JSON support not compiled-inon every removal, and the CNI agent retries indefinitely. The new check detects this error at startup and falls back to theiptablesbackend. (Issue #60328)Added
prefix_rewritefield toHTTPRedirect, enabling prefix-aware path rewriting in redirect rules. This allows stripping or replacing the matched path prefix while redirecting, e.g. redirectingexample.com/foo/bartofoo.example.com/bar. (Issue #47500),(Issue #47777),(Issue #52521)Added the
budget_intervalfield to theRetryBudgetTrafficPolicyAPI to configure the interval with which requests are considered when calculating the retry budget. The default value, 0ms, retains the existing behavior of considering only in-flight requests. (Issue #60389)Added support for weighted waypoint canaries in ambient mode. A service (or namespace) can now reference a primary and a canary waypoint via the
istio.io/use-waypoint-canaryandistio.io/use-waypoint-canary-namespacelabels, with theistio.io/use-waypoint-canary-weightannotation directing a configurable share of the service’s in-mesh connections (and, withistio.io/ingress-use-waypoint, ingress requests) to the canary waypoint without any client changes. (Issue #60801)Added
meshConfig.serviceEntryVisibility, letting a mesh administrator control the visibility ofServiceEntryresources. Ambient (ztunnel and waypoints) enforces visibility by default; classic sidecars additionally honor it whenapplyToSidecarsis set. The feature is inert unless configured, so existing meshes are unaffected by default. (Issue #60870)Added the
istio-agentgateway-waypointGatewayClassfor deploying agentgateway as a waypoint.Added
ALLOW_ANY_DYNAMIC_DNSoutbound traffic policy mode. When set inmeshConfig.outboundTrafficPolicy.mode, plaintext HTTP requests to unknown destinations are forwarded via Envoy’s Dynamic Forward Proxy, resolving hostnames from theHostheader at request time. Non-HTTP traffic (TLS and raw TCP) continues to usePassthroughCluster. Scoped to sidecar proxies only. Not supported in theSidecarCRD. Optional upstream TLS origination can be configured viameshConfig.outboundTrafficPolicy.tls.Added support for
connectionSettingsinProxyConfig, allowing configuration of listener buffer limits, HTTP timeouts, HTTP/2 settings, and path/header normalization. The newEDGEprofile applies opinionated Envoy edge-proxy defaults to gateway proxies.Added a new
MERGE_AND_REPLACE_LISTpatch operation toEnvoyFilter. It behaves likeMERGE, except that repeated (list) fields present in the patch fully replace the corresponding list in the generated configuration instead of being appended to it. This applies to theCLUSTER,LISTENER,FILTER_CHAIN,ROUTE_CONFIGURATION,VIRTUAL_HOST, andHTTP_ROUTEpatch targets. Lists nested insideAny-typed filter configurations (HTTP, network, and listener filters, and transport sockets) are not affected and continue to followMERGEsemantics.Added implementation of the Gateway API
AllowInsecureFallbackfeature in the client certificate validation logic. This feature allows a gateway to request a client certificate and try to validate it, but if the client does not present a certificate, or the certificate is not valid, the gateway will still allow the connection. By default, Istio populates thex-forwarded-client-certHTTP header, so whenAllowInsecureFallbackis enabled, the backend can verify the certificate instead of the gateway. (Issue #60018)Added support for configuring HTTP/2 keepalive PING settings on upstream connections through
DestinationRule. (Issue #55640)Added
defaultTrafficPolicytoMeshConfig, a mesh-wide baselineconnectionPoolandoutlierDetectionthat outbound clusters inherit. ADestinationRulethat sets one of these blocks overrides the baseline for that block; a block theDestinationRuleleaves unset now inherits the mesh baseline instead of Istio’s built-in defaults. When no baseline is configured, behavior is unchanged. The baselineconnectionPoolis also applied to inbound clusters and the passthrough cluster.Added support for Envoy’s zone-aware load balancing via a new
zoneAwareLbSettingfield onDestinationRule.TrafficPolicy.LoadBalancerSettingsandMeshConfig. When enabled, Envoy automatically routes traffic to endpoints in the same availability zone as the downstream proxy, spilling over to other zones only when local capacity is insufficient. This differs from the existinglocalityLbSettingin that zone-level routing is handled automatically by Envoy using the proxy’s zone distribution, rather than through static percentages. Cross-region failover ordering can be configured via thefailoverfield, and label-based priority tiers can be layered on top viafailoverPriority. Zone-aware load balancing requiresISTIO_META_ENABLE_SELF_DISCOVERY: "true"inmeshConfig.defaultConfig.proxyMetadatato inject the self-discoverylocal_clusterinto sidecar bootstraps. It is supported in sidecar mode only, and is not supported in ambient mode. (reference)(reference)Enabled sending unhealthy endpoints by default unless
OutlierDetection.minHealthPercentis configured. This can be disabled by settingPILOT_AUTO_SEND_UNHEALTHY_ENDPOINTStofalse.Fixed Gateway API handling to implement
BackendTLSPolicyconflict resolution. (Issue #57817)Fixed a bug where inbound clusters were missing for proxies that reconnected to a new istiod instance (e.g. during rolling restarts) when the pod was not yet present in the kube informer cache. Workload labels are now populated before service targets are computed, so the metadata fallback path in
GetProxyServiceTargetscorrectly matches services instead of returning an empty list. (Issue #58125)Fixed an issue where, when
PILOT_ENABLE_QUIC_LISTENERSis enabled, generated Gateway APIServiceresources did not listen on the corresponding UDP port for each HTTPS listener. (Issue #58247)Fixed an issue where HTTPS listeners defined via
ListenerSetfailed to deliver TLS certificates when the parent Gateway used manual deployment. (Issue #59535)Fixed an issue where
HTTPRouteandGRPCRoutefilters with invalid header values were silently dropped from the Envoy config instead of reporting anInvalidFilterstatus. (Issue #59933)Fixed a brief traffic outage when changing the
istio.io/revlabel on a Kubernetes Gateway (orListenerSet). The previously-owning control plane no longer drops the resource and pushes empty xDS config to gateway pods that are still running on the old revision. Status writes for non-owning revisions are still suppressed, so revisions do not flap on each other’s status. (Issue #59959)Fixed multi-network ambient so that it now routes to the waypoint when the ingress on one network calls a service on a different network, and only if the
Serviceis configured withistio.io/ingress-use-waypoint.Fixed an issue where the waypoint listener config on IPv6 clusters contained an
IPMatcher.RangeMatcherwith an emptyrangesfield when a headless Service (spec.clusterIP: None) was present in the waypoint’s scope. This was produced because the IPv4-encodedconstants.UnspecifiedIPplaceholder used for headless services’DefaultAddressis filtered out for IPv6-only proxies byFilterAddressesByIPFamily. Envoy 1.38 strict-validates the proto’srepeated.min_items=1rule onIPMatcher.RangeMatcher.rangesand rejects the LDS push. The waypoint listener builder now elides theIPRangeMatcherentry when there are no addresses to put into it, matching the existing behavior of the surrounding code that already removes the hostname half fromsvcHostnameMapfor the same case. IPv4 clusters are unaffected behaviorally — the placeholder matcher that was previously emitted matched nothing. (Issue #60310)Fixed an issue where
consistentHashload balancing inDestinationRulewould not send traffic to new endpoints after scaling, due to an Envoy regression (envoyproxy/envoy#45212) where the RING_HASH ring was not rebuilt on endpoint changes during batched updates. (Issue #60312)Fixed a fatal
concurrent map writespanic in theistio-cniagent when two pods were added to the ambient mesh on the same node at the same time. (Issue #60328)Fixed a
DestinationRuleand a Gateway API backend policy (BackendTLSPolicyorXBackendTrafficPolicy) targeting the same host so that theDestinationRulefields now take precedence and the backend policy only fills in fields theDestinationRuleleaves unset, regardless of which was created first. (Issue #60358)Fixed an ambient mode bug where a single Service combining
publishNotReadyAddresses: truewith aPreferSameZoneorPreferSameNodetraffic distribution caused ztunnel to receivehealthPolicy: AllowAllfor every other Service using the same traffic-distribution preset, leading to traffic being routed to not-ready endpoints cluster-wide. (Issue #60422)Fixed an issue where proxy draining could panic instead of returning an error when the Envoy admin endpoint was unavailable.
Fixed an issue where additional namespaces in
meshConfig.defaultServiceExportToandmeshConfig.defaultVirtualServiceExportTowere not honored when the default included the current namespace as.. (Issue #60560)Fixed a bug where removing a listener from a
ListenerSetleft an orphaned entry in the resource’sstatus.listenersindefinitely. The stale entry madestatus.listenerslonger thanspec.listenersand, after repeated listener add/remove cycles, wedged theListenerSet’sobservedGenerationso later spec changes were no longer reflected in its status.reportListenerSetStatusnow prunes status entries for listeners that are no longer present in the spec, matching the existing behavior forGatewayresources. (Issue #60578)Fixed
DestinationRulevalidation incorrectly rejecting warmup aggression values between 0 and 1. (Issue #3395),(Issue #55153)Fixed a bug where istiod did not pick up updated remote cluster secrets (e.g. during credential/token rotation) until restarted. The new cluster registry could deadlock waiting to sync, leaving the service registry stale for the affected remote cluster. (Issue #60612)
Fixed an issue introduced in Istio 1.30 where metadata-only changes to
VirtualServiceresources (e.g. Helm annotations, Argo CD labels, orkubectl.kubernetes.io/last-applied-configuration) triggered unnecessary XDS pushes to all proxies. This could cause a significant increase in control plane CPU usage and push latency in clusters with manyVirtualServiceresources managed by GitOps tooling. The fix restores the pre-1.30 behavior where only spec changes oristio.iolabel/annotation changes trigger a push. (Issue #60629)Fixed duplicate and excessive pushes when using
WasmPluginresources due toTrafficExtensionconversions.Fixed a deadlock where the
istio-cninode agent pod could fail to start (for example after a node reboot) because the CNI plugin only skipped the kube client creation for its own agent pod when ambient mode was enabled. The preemptive check now runs in sidecar mode as well, so the agent pod no longer blocks on a kubeconfig it has not written yet. (Issue #60668)Fixed default HTTP retries for inbound routes of waypoints. The
meshConfig.defaultHttpRetryPolicysetting now applies to local services attached to waypoints. (Issue #60682)Fixed an issue where
EXIT_ON_ZERO_ACTIVE_CONNECTIONSnever fired on ambient ingress gateways and waypoints because pilot-agent’s drain loop counted in-process connections on Envoy’s HBONE internal listeners (connect_originate,connect_terminate,main_internal, etc.), preventing the active-connection count from reaching zero and forcing the proxy to wait untilterminationGracePeriodSeconds. (Issue #60728)Fixed an issue where the
service.istio.io/canonical-namelabel could end with an invalid.or_when truncated to 63 characters in the injection template.Fixed an issue where an
HTTPRoutewith empty or omittedbackendRefsreturned an HTTP 404 status code instead of 500. This matches the behavior enforced by theHTTPRouteNoBackendRefsGateway API conformance test, introduced in v1.6.0.Fixed an issue where the advertised HBONE capability was not propagated onto auto-registered
WorkloadEntryresources for non-Kubernetes workloads.Fixed an issue where the
Acceptedcondition on aGatewaywas not set toFalsewhen referencing an invalid or non-existentparametersRef. This matches the behavior enforced by theGatewayInvalidParametersRefGateway API conformance test, introduced in v1.6.0.Fixed cross-network traffic through the east-west gateway being blocked by a spurious deny-all RBAC filter when the destination service has L7
AuthorizationPolicyresources. (Issue #60806)Fixed a bug where a remote cluster’s network gateway could disappear from cross-network routing after credential rotation and not recover until istiod restarted. The in-place registry swap now re-wires the new registry to the aggregate controller’s handlers so its future gateway and service events propagate, and reloads gateways once to pick up those discovered during the pre-swap sync. (Issue #60920)
Fixed an issue in multicluster deployments where rotating a remote cluster’s
istio-remote-secretcould permanently wipe endpoint shards for services with stable endpoints in that cluster, making them unreachable across clusters until istiod was restarted. (Issue #61043)Fixed an issue where
consistentHashload balancing in aDestinationRuledid not work for services routed through a waypoint proxy in ambient mode when noVirtualServicewas present. The Envoy cluster correctly receivedlb_policy: RING_HASHbut the inbound route was missinghash_policy, causing Envoy to fall back to random backend selection and breaking sticky sessions. A no-op passthroughVirtualServicewas previously required as a workaround. (Issue #61045)Fixed a race condition on istiod startup where the readiness probe could report ready before the dedicated injection and validation webhook server (
--httpsAddr, default:15017) was accepting connections, causing intermittentfailed calling webhooktimeouts when creating resources immediately after istiod became ready. This does not affect deployments where webhooks share the main HTTP server (empty--httpsAddr). (Issue #61049)Fixed an issue where ingress gateways bypassed waypoint proxies for multi-cluster services when remote workloads were on a different network, causing authorization policies to not be enforced. (Issue #61092)
Fixed an issue where gateway proxy Deployments could permanently fail to be created during istiod startup. (Issue #61095)
Fixed an issue where a pod selected by a
ServiceEntryworkloadSelectorcould start up missing that service from its sidecar’s inbound configuration. Traffic to the port was not handled as the protocol declared in theServiceEntry, and port-levelPeerAuthenticationwas not applied. The pod did not recover on its own; only restarting istiod repaired it. (Issue #61157)Fixed an issue where
istio-cniconsideredhostNetworkpods eligible for ambient enrollment. (Issue #61168)Fixed an issue where, due to a number of problems, pilot ignored
ListenerSetresources and the routes attached to them when generating configuration for agentgateway. Pilot no longer filters outListenerSetresources and their attached routes, enabling agentgateway in Istio to handleListenerSetresources properly.Fixed
ListenerSetstatus reporting when aListenerSetis not allowed by the parentGatewayresource for agentgateway. When aListenerSetis not allowed by the parentGateway, theAcceptedcondition status is now reported asFalse, which was not previously the case. Additionally, because theListenerSetfeature is no longer experimental as of Gateway API v1.5.0, it is no longer guarded by thePILOT_ENABLE_ALPHA_GATEWAY_APIfeature flag.Fixed an issue where an agentgateway
Gatewayconnected to sidecar-injected (mesh) backends using plaintext instead of Istio mutual TLS. Previously, raw TCP routed to a mesh backend (viaTCPRoute, or aTLSRoutein Terminate mode) could hang for server-first protocols — where the backend speaks first, such as SMTP or MySQL — and backends enforcingSTRICTmutual TLS were unreachable.Fixed a memory and goroutine leak in Istiod ambient multi-cluster mode where the per-cluster node locality collections were scoped to the process lifetime instead of the cluster lifetime, so they were never torn down when a remote cluster was removed. (Issue #60033)
Fixed a bug in Istiod ambient multi-cluster mode where the aggregated (local + remote) collections could report themselves as synced before the remote clusters had been discovered and synced. As a result, Istiod could begin serving with local-cluster-only data, temporarily omitting workloads, services, and endpoints from remote clusters at startup. The aggregated collections now wait for the multi-cluster controller and every remote cluster’s collections to sync before being marked ready.
Fixed an issue where an ambient-enrolled pod could be left out of the host health-probe ipset following a node or kubelet restart, causing kubelet probes to be redirected to ztunnel and rejected until the
istio-cninode agent restarted. On startup the node agent could evict still-enrolled pods from the ipset when their IP was not yet observable, and it now re-asserts probe ipset membership for enrolled pods during reconciliation.Fixed a file descriptor leak in the
istio-cninode agent: when the procfs scan found more than one network namespace for the same pod, the losing candidate’s netns file descriptor was dropped without being closed, pinning the namespace in the kernel until garbage collection.Fixed a deadlock in the ambient CNI node agent where a pod deletion event concurrent with a ztunnel (re)connection could permanently block the ZDS server. (Issue #1674)
Fixed an issue where endpoint mTLS mode was not derived from the
DestinationRuletop-level traffic policy when a targeted subset did not specify a TLS mode for the port. The subset traffic policy now correctly falls back to theDestinationRule-level TLS setting.Fixed status reporting for certificate references in
Gatewayresources to comply with the Gateway API specification v1.5.0. It changes theGatewaystatus to report conditions of typeResolvedRefs, and also adds extra details to theAcceptedcondition when it fails due to invalid or non-existent certificates.Fixed the
Acceptedcondition on a KubernetesGatewayto reflect the validity of its listeners. When one or more listeners are not accepted (for example, an unsupported listener protocol), theGatewaynow reports theListenersNotValidreason, and is only set toAccepted=Falsewhen none of its listeners are accepted. Previously theGatewaywas always reported asAcceptedregardless of its listeners.Fixed an issue where proxyless gRPC xDS clients could receive over-broad RDS
RouteConfigurationresponses from Istiod.Fixed a bug where an internal listener was incorrectly created when the listener was of type HTTPS or TLS but had no TLS section defined. A following version of the Gateway API will prevent this combination of inputs from ever reaching a controller. (Issue #60562)
Fixed config generation for sidecars prior to 1.29.2.
Fixed an istiod panic when processing a
VirtualServicewith TCP or TLS routes that have no destinations, which could occur when the validating webhook is not installed (e.g. deployments without a default revision). (Issue #60110)Fixed goroutine and memory leaks in istiod in ambient multi-cluster mode when remote clusters are removed or updated. The internal collections built for each remote cluster did not release the event handlers they had registered on their inputs when torn down, causing goroutines and memory to accumulate over time as clusters were removed or reconfigured. (Issue #60033)
Fixed a memory leak in the
krtcontroller framework where changing the key used in aFetchfilter (for example, relabeling a pod to point to a different waypoint) left stale reverse-index entries that were never cleaned up. Over time this could grow memory usage and cause unnecessary recomputations.Fixed a goroutine leak in istiod leader election where every election cycle (leadership lost and re-acquired) leaked one goroutine until process exit. (Issue #60843)
Fixed ListenerSet status reporting so that a ListenerSet with no valid listeners now reports the
AcceptedandProgrammedconditions asFalsewith reasonListenersNotValid. Previously the ListenerSet-level conditions could remainTrueeven when none of its listeners were usable.Fixed a deadlock in the multicluster
ClusterStorewhereAllReadycould recursively acquire the storeRWMutexfor read viatriggerRecomputeOnSync->GetByIDwhile a writer was waiting, blocking further reads and writes against the store.Fixed ambient multi-cluster serving a stale snapshot of a remote cluster after its credentials were rotated. The per-cluster collections were cached by cluster ID alone, so a secret update carrying a new kubeconfig kept reusing the collections built for the previous generation, whose client and informers are shut down once the new one syncs. They are now cached per generation and rebuilt on the new client. (Issue #60033)
Fixed a memory leak in Istiod where
needResyncentries for failed pod IPs were never cleaned up.Fixed failover routing when the network is included. The network is considered preferred, but not required, when determining failover priority. For example,
PreferSameZonehas the following priority order: Network+Region+Zone, Network+Region, Network, Region+Zone, Zone, and no match.Fixed generated
GatewayServiceresources being rejected when two listener names sanitize to the sameServiceport name (names differing only by periods versus dashes, or only past the 63-character limit), which blocked every unpublished port on theGateway. Colliding port names are now disambiguated with the listener’s port number.Fixed a bug where the
istio-cninode agent could pair an ambient pod with another pod’s network namespace when a third-party process was inside that namespace during a scan, which could cause traffic to be proxied with the wrong identity. The node agent now verifies that a namespace holds one of the pod’s IPs before enrolling the pod. (Issue #61211)Fixed a bug where a ztunnel reconnect (such as the periodic connection recycle from
keepaliveMaxServerConnectionAge) triggered a full workload (WDS) push. Istiod now assigns each WDS resource a content-based version and, when a reconnecting client reports the versions it already holds viainitial_resource_versions, re-sends only resources that changed while the client was disconnected. Older ztunnel versions that do not report versions continue to receive the full set. (Issue #1966)Fixed
zoneAwareLbSetting.enabled: falseto explicitly disable Envoy’s intrinsic zone-aware routing by emittingrouting_enabled: 0%. Previously,enabled: falsewas a no-op: Istio emitted noZoneAwareLbConfig, causing Envoy to fall back to its defaultrouting_enabled: 100%, which engaged zone-aware routing automatically whenever a self-discovery local cluster was present. This made gradual rollout unsafe, as pods in a mixed state (some with self-discovery, some without) would unevenly distribute traffic.Upgraded version of
nftablesused by Istio distroless images. Thenftablesversion was previously pinned to 1.1.1 to avoid a bug that could cause older versions ofnftableson K8s nodes to crash after Istio used a newer version packaged in its images on the same node.Major Linux distributions have been informed of the issue and have released fixes. As a result, Istio is removing the
nftablesversion pinning. Users are advised to update thenftablespackage on their nodes to the latest available version to ensure that the fixed version is installed.If you continue to experience
nftablescrashes on your nodes, downgrade to an older version of Istio and contact your node OS provider to request that the fix be backported to your OS version. (Issue #58492)Optimized sidecar egress service resolution: listeners that import only exact (non-wildcard), explicitly-namespaced hosts now resolve services through direct service-index lookups instead of scanning every service visible to the namespace, reducing the per-listener cost from
O(services)toO(imported hosts)and eliminating the full-list allocation. (Issue #60473)
Security
Added
PILOT_ENABLE_STRICT_GATEWAY_MERGINGto prevent cross-namespace merging of IstioGatewayresources with managed Gateway APIGatewayresources. When enabled (the default), IstioGatewayCRDs from different namespaces are not merged with managed Gateway APIGatewayproxies. Unmanaged (manual deployment) Gateway APIGatewayresources are not affected. SetPILOT_ENABLE_STRICT_GATEWAY_MERGINGtofalseto disable.Added
trustDomainsandnotTrustDomainsfields to theSourceinAuthorizationPolicy, allowing users to match or exclude requests based on the trust domain derived from the peer certificate.Added support for
fips-140-3as a new value for theCOMPLIANCE_POLICYenvironment variable. This enforces TLS 1.2 or 1.3 with FIPS-compliant cipher suites (ECDHE_[RSA|ECDSA]WITH_AES_GCM_SHA for TLS 1.2, AES-GCM for TLS 1.3) and restricts key agreement to P-256 or P-384 curves. On the Envoy proxy side, this uses the nativeFIPS_202205compliance policy. Go components (istiod, istio-agent) must be built with Go 1.24+ usingGOFIPS140=v1.0.0(or later validated version) to enable the native Go FIPS 140-3 cryptographic module. TheGODEBUG=fips140=onlyenvironment variable is automatically injected at runtime for sidecars, gateways, and the istiod control plane whenCOMPLIANCE_POLICYis configured via the Helmenvvalue (e.g.,--set pilot.env.COMPLIANCE_POLICY=fips-140-3). Note:GOEXPERIMENT=boringcrypto(used for FIPS 140-2) is incompatible with this policy and must not be used. BoringCrypto targets FIPS 140-2 only and conflicts with Go’s native FIPS 140-3 module.Added a new environment variable
PILOT_ENABLE_REMOTE_CREDENTIALS_CONTROLLER(defaulttrue) which toggles credential controllers for remote clusters.Fixed pilot-agent missing certificate reloads on second and subsequent Kubernetes secret rotations for file-mounted certs. (Issue #59912)
Fixed an issue where
caCertificateRefs[].kind: Secretin Gateway API frontend mTLS (spec.tls.frontend.default.validation.caCertificateRefs) was rejected by SDS at runtime despite validGatewayconfiguration, including same-namespace references and cross-namespace references allowed byReferenceGrant. (Issue #60277)Fixed an
EnvoyFiltervalidation gap where an uncappedproxyVersionmatch expression could drive excessive istiod memory and CPU during regex compilation. The match expression is now limited to 1024 characters.Credit: This issue was reported by Artem Cherezov (cherez0ff).
Fixed external SDS providers configured through
extensionProvidersto use the configured service hostname as the gRPC authority.Fixed external SDS provider for gateways to use the credential name (after stripping the
sds://prefix) as the SDS resource name instead of the provider name. This allows multiple gateways using the same SDS provider to request different certificates. ForMUTUALTLS, the CA certificate resource name is correctly derived as<credential-name>-cacert. When neither a UDS socket nor an SDS extension provider is configured, the gateway now falls back to fetching certificates via ADS (Kubernetes Secrets) instead of failing silently. (Issue #57080)Fixed a bug where istiod did not reload its CA root certificate when it rotated if the certificate is provided via files (for example, when using an external CA such as istio-csr).
Fixed the XDS
apigenerator (MCP config serving) to require a verified control-plane identity. Previously, any client that could reach istiod’s XDS port could read Istio config across all namespaces. Disable withENABLE_XDS_API_GENERATOR_AUTH=falseif needed for compatibility.
Telemetry
Improved the pilot-agent’s
/stats/prometheusendpoint to concurrently scrape multiple targets declared by theprometheus.istio.io/scrape-targetsannotation and merge the output in the declared order. Single-target pods keep the existing streaming code path byte-for-byte. For multi-target pods, OpenMetrics responses are rewritten so the merged output contains exactly one# EOFterminator. Individual target metrics responses are capped at 10 MiB to bound agent memory; responses exceeding this limit are dropped and counted as scrape failures. Per-target scrape failures are non-blocking and incrementistio_agent_scrape_failures_total{type="application"}. (Issue #59567)Added a new environment variable
PILOT_AGENT_MERGE_ENVOY_STATSto control whether pilot-agent merges Envoy stats into its stats endpoint. Set tofalseto disable merging Envoy stats with agent stats.Added a new metric,
istio_cni_plugin_requests_total, to theistio-cninode agent. It counts CNI plugin add-event requests handled by the node agent, labeled byresponse_code. (Issue #60878)Added a new pod annotation
prometheus.istio.io/scrape-targetsthat lets users declare multiple application-metrics endpoints per pod as a comma-separatedport:pathlist. Targets colliding with the agent status port or any Istio-reserved data-plane port are rejected at injection time with a human-readable error. (Issue #59567)Added two new opt-in environment variables,
ENVOY_SECURE_METRICS_PORTandENVOY_SECURE_MERGED_METRICS_PORT, that expose mTLS-protected Prometheus scrape endpoints on every Envoy sidecar proxy. When set, the sidecar adds static bootstrap listeners on the configured ports that require mutual TLS, allowing Prometheus to scrape metrics securely without relying on pod-network-level access controls. See the RFC for details. (Issue #50114)Fixed an issue where pilot-agent metric merging produced an incorrect result when Envoy reported metrics using the protobuf content type. The logic implemented in pilot-agent cannot handle the protobuf content type correctly, so this change restricts the allowed content types to
text/plainandapplication/openmetrics-textonly. (Issue #60322)Removed the
PILOT_SPAWN_UPSTREAM_SPAN_FOR_GATEWAYfeature flag. The behavior of spawning upstream spans for gateway requests is now always enabled. Users who previously set this tofalseshould remove that configuration, as it will no longer have any effect.
Extensibility
Fixed a bug where a
Servicereferring to a waypoint in a different namespace did not have the namespace-wideTelemetryresource included as part of its configuration. (Issue #60665)Fixed a bug where a
WasmPluginin an application namespace targeting aServiceviatargetRefswould cause a waypoint proxy to crash-loop on startup. The LDS path correctly included the plugin for the waypoint, but the ECDS lookup path rejected it as cross-namespace, leaving Envoy waiting for a resource that would never arrive. (Issue #60530)
Installation
Updated Kiali addon to version v2.26.0.
Added the
ZTUNNEL_RESOURCE_CPU_LIMITandZTUNNEL_RESOURCE_CPU_REQUESTenvironment variables to the ztunnelDaemonSet, populated from the configuredresources.limits.cpu/resources.requests.cpuwhen set. ztunnel uses these to derive CPU-aware worker-thread counts.Added the
terminationMessagePolicyHelm field for the istiod (pilot) container, allowing configuration of how termination messages are populated.Added
dnsPolicyanddnsConfigfields to the gateway Helm chart for custom DNS configuration in environments with non-standard DNS requirements.Added an
-o/--outputflag toistioctl manifest generatethat writes the generated manifest to a file instead of stdout. This avoids relying on shell redirection, which is convenient for automation and required in environments where no shell is available (for example, hardenedistioctlimages that ship without one).Added
values.global.readerServiceAccountwithnameandnamespacefields to bind theistio-readerClusterRoleto a custom service account. When set, the defaultistio-reader-service-accountis not created, and theClusterRoleBindingreferences the specified service account instead. Settingglobal.enableReaderRBACtofalsesuppresses theistio-readerClusterRoleandClusterRoleBindingregardless ofreaderServiceAccountsettings.Fixed an issue where the
istio-initcontainer would use the wrong image whenglobal.proxy_init.imageandglobal.proxy.imagewere configured differently. (Issue #59066)Fixed the waypoint and kube-gateway workload-socket volume being incompatible with the SPIRE CSI driver configuration. (Issue #60108)
Fixed Helm chart rendering when
global.istioNamespaceor the release namespace is numeric-only (for example,1234). Namespace fields in rendered manifests are now quoted so YAML parsers treat them as strings instead of numbers. (Issue #60239)
istioctl
Added support for
istioctl remote-clustersto display revisions.Added an
istioctl analyzewarning (IST0177) for when multipleServiceEntryresources define the same host and port with conflicting protocols. (Issue #60447)Added an
istioctl analyzecheck,IST0176, that flags Gateway API CRDs installed at a version below the minimum required by the current Istio version. Resources backed by such CRDs are silently filtered by istiod, which previously made TLS passthrough breakage after upgrading to Istio 1.30 with stale Gateway API CRDs hard to discover.Fixed
istioctlfailing to discover istiod when Istio is installed in a non-default namespace (other thanistio-system) with a revision tag. TheDefaultWatchernow constructs the expected webhook name based on the Istio namespace passed via the-iflag. (Issue #60232)Fixed
istioctl tag removenot deleting theistiod-default-validatorValidatingWebhookConfigurationwhen removing the default revision tag. (Issue #60537)Fixed an issue where
istioctlmanifest--setvalues containing=were parsed as malformed input.