π Recommended Actions
β οΈ Action Required
Immediate upgrade is recommended. Critical bugs affecting Ambient mesh traffic distribution and CNI stability have been fixed. Review Gateway API header validation changes and unmanaged Gateway SA behavior.
π Summary
Istio 1.29.4 delivers crucial stability and correctness enhancements, particularly for Ambient mesh deployments and Gateway API users. This patch release resolves a critical bug where PreferSameZone or PreferSameNode traffic distribution, combined with publishNotReadyAddresses: true, could lead to traffic being routed to unready endpoints cluster-wide. Another significant fix addresses a concurrent map writes panic in the CNI agent, improving Ambient mesh robustness. Gateway API users benefit from new header validation logic, preventing silently dropped configurations and providing clearer feedback for invalid HTTPRoute and GRPCRoute header values. Multi-network Ambient ingress routing also sees improvements, ensuring correct waypoint traversal based on configuration. This release also streamlines HTTP/2 handling and includes numerous dependency updates, reinforcing overall platform reliability. Upgrade now to secure these vital fixes and bolster your Istio environment.
π Critical Ambient Mesh Traffic Distribution Fix
A severe bug in Ambient mode’s traffic distribution logic has been resolved, preventing incorrect routing to unready endpoints. Previously, if a service was configured with publishNotReadyAddresses: true and a PreferSameZone or PreferSameNode traffic distribution, the HealthPolicy: AllowAll setting could inadvertently leak to all other services utilizing the same traffic distribution preset. This led to ztunnel routing traffic to unready endpoints cluster-wide, significantly impacting service reliability.
The fix addresses the underlying issue by ensuring that preferSameZoneLoadBalancer and preferSameNodeLoadBalancer now return fresh workloadapi.LoadBalancing objects on each call. This prevents mutations made for one service (e.g., setting HealthPolicy to ALLOW_ALL for publishNotReadyAddresses: true) from affecting the shared, global preset, thus maintaining correct health policy enforcement for all services.
// Old behavior (shared pointer, prone to mutation leaks)
// var preferSameZoneLoadBalancer = &workloadapi.LoadBalancing{...}
// New behavior (returns fresh object on each call)
func preferSameZoneLoadBalancer() *workloadapi.LoadBalancing {
return &workloadapi.LoadBalancing{
RoutingPreference: []workloadapi.LoadBalancing_Scope{
workloadapi.LoadBalancing_NETWORK,
workloadapi.LoadBalancing_REGION,
workloadapi.LoadBalancing_ZONE,
},
Mode: workloadapi.LoadBalancing_FAILOVER,
}
}
Source:
pilot/pkg/serviceregistry/kube/controller/ambient/services.go(686-708)pilot/pkg/serviceregistry/kube/controller/ambient/services_test.go(1121-1160)releasenotes/notes/60423.yaml(0-8)
π οΈ Ambient CNI Stability: Concurrent Map Write Fix & NFTables JSON Probe
Istio’s CNI agent, a crucial component for Ambient mesh, receives significant stability enhancements in this release. A critical race condition, where concurrent pod additions could trigger a fatal error: concurrent map writes panic, has been resolved. Additionally, the CNI now intelligently probes the underlying nft binary for JSON output support, falling back to iptables if libjansson is missing. This prevents indefinite retries and improved resilience on diverse Linux environments.
The NftablesConfigurator no longer holds a shared ruleBuilder field. Instead, a new NftablesRuleBuilder instance is created per-call within AppendInpodRules, eliminating the race condition:
// Before: cfg.ruleBuilder = builder.NewNftablesRuleBuilder(config.GetConfig(cfg.cfg))
// After:
rb := builder.NewNftablesRuleBuilder(config.GetConfig(cfg.cfg))
// ... use rb for rule appending ...
return cfg.executeCommands(rb) // pass rb to execution
For NFTables JSON support, the CNI agent executes nft --json list tables at startup. If the output contains JSON support not compiled-in, it defaults to the iptables backend. This ensures the CNI functions correctly even when nft lacks a required build-time dependency for certain operations.
// Example of the JSON probe logic
func detectNftJSONSupport() (bool, error) {
// ... snipped for brevity ...
out, err := cmd.CombinedOutput()
outStr := string(out)
if strings.Contains(outStr, nftJSONNotCompiledMarker) {
return false, nil // JSON support missing, fall back
}
// ... other error handling ...
return true, nil // JSON support present
}
Source:
cni/pkg/nftables/nftables.go(60-61, 131-389)cni/pkg/nftables/nftables_test.go(189-216)cni/pkg/nodeagent/detect_nft_json_linux.go(0-51)cni/pkg/nodeagent/detect_nft_json_linux_test.go(0-71)cni/pkg/nodeagent/server_linux.go(73-84)releasenotes/notes/60328.yaml(0-17)
π Enhanced Gateway API Header Validation
Operating your ingress with the Gateway API just got more robust. This release introduces strict validation for HTTPRoute and GRPCRoute header modifier filters. Previously, specifying invalid characters (like newlines or control characters) in header values would cause the filter to be silently dropped from the Envoy configuration, leading to unexpected behavior. Now, such invalid configurations are explicitly flagged with an InvalidFilter status, providing clearer feedback and preventing silent failures.
A new isValidHeaderValue function checks for HTTP header value conformity, disallowing characters such as newline (0x0A), carriage return (0x0D), null (0x00), and the Delete character (0x7F), among others. Only tab (0x09) and printable ASCII characters (0x20 to 0x7E, excluding 0x7F) are permitted.
Here’s an example of an invalid header value that will now be rejected:
# This HTTPRoute filter will now be marked as InvalidFilter
spec:
rules:
- filters:
- type: RequestHeaderModifier
requestHeaderModifier:
set:
- name: malformed-header
value: "value with\nnewline"
The system now accurately reports the InvalidFilter status for such configurations, helping operators quickly identify and correct issues.
Source:
pilot/pkg/config/kube/gateway/conversion.go(139-1048)pilot/pkg/config/kube/gateway/conversion_test.go(1631-1736)releasenotes/notes/59933.yaml(0-10)
π Gateway API & Ambient Mesh Routing Improvements
This release brings vital improvements to both Gateway API handling and Ambient mesh multi-network routing. For Gateway API users, a fix ensures HTTPS listeners on ListenerSet resources correctly deliver TLS certificates when the parent Gateway is manually deployed. Meanwhile, Ambient mesh’s multi-network capabilities are enhanced, providing more nuanced control over waypoint traversal for ingress traffic, ensuring L7 policies are applied as intended.
The serviceAccountName for ListenerSet-derived configurations will now be empty when the parent Gateway is unmanaged (manual deployment). This prevents unintended service account restrictions and allows manual deployments to function correctly:
# Example of ListenerSet generated config with empty service-account-name
metadata:
annotations:
internal.istio.io/service-account-name: "" # This will now be empty for unmanaged Gateways
For Ambient multi-network routing, the x-istio-source header in DoubleHBONEOuterConnectOriginate is now dynamically set based on the proxy type (waypoint, gateway, sidecar). This allows East/West gateways to make more intelligent routing decisions. Specifically, ingress traffic on one network calling a service on another network will now correctly route via the waypoint only if the service has istio.io/ingress-use-waypoint explicitly enabled. This is crucial for maintaining L7 policy enforcement across network boundaries.
// Simplified logic for x-istio-source header assignment
var source string
switch proxy.Type {
case model.Router: source = downstreamSourceGateway
case model.Waypoint: source = downstreamSourceWaypoint
case model.SidecarProxy: source = downstreamSourceSidecar
}
// Within buildWaypointInternal, dispatch is conditional:
// m.Map[downstreamSourceWaypoint] = match.ToChain(tcpChain.Name)
// if ingressUseWaypoint { m.Map[downstreamSourceGateway] = match.ToChain(waypointClusterName) }
// else { m.Map[downstreamSourceGateway] = match.ToChain(tcpChain.Name) }
// m.OnNoMatch = match.ToChain(waypointClusterName)
Source:
pilot/pkg/config/kube/gateway/gateway_collection.go(164-177)pilot/pkg/config/kube/gateway/testdata/listenerset-cross-namespace.yaml.golden(25-25)pilot/pkg/model/gateway_test.go(64-88)pilot/pkg/networking/core/listener.go(1508-1533)pilot/pkg/networking/core/listener_waypoint.go(255-409)releasenotes/notes/59535.yaml(0-8)releasenotes/notes/60162.yaml(0-8)tests/integration/ambient/multinetwork_test.go(240-279)tests/integration/ambient/waypoint_test.go(1308-1332)
Minor Updates & Housekeeping
This release includes routine dependency updates for several Go modules, bumps to proxy and ztunnel SHAs, and removes some old license files for unused dependencies. Internal HTTP/2 and h2c handling logic has been simplified and refactored for better maintainability.