You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Description:
Active health check per-endpoint hostname override blocked by wildcard Host: "*"
Summary
When using active HTTP health checks with Backend FQDN endpoints on routes that match by headers (no hostname), the per-endpoint health check hostname override introduced in #8452 does not take effect. The health check Host header is set to "*", causing all endpoints to fail active health checks and triggering envoy panic mode, which is not the purpose of health-check-based failover.
Each endpoint should have its own Host header in the health check request, derived from the Backend endpoint's hostname field via Endpoint.HealthCheckConfig.Hostname (the per-endpoint override path added in #8452).
Actual Behavior
The health check sends Host: "*" for all endpoints. The per-endpoint health_check_config is empty in the xDS config despite the Backend endpoint hostname field being properly populated.
This causes:
All endpoints fail active health checks (upstream rejects Host: *)
Envoy enters panic mode (100% unhealthy exceeds the 50% healthy_panic_threshold)
Traffic is load balanced blindly across all endpoints, including unhealthy ones
Clients see errors when requests hit the downed backend — no failover
// No route hostnames specified: use the listener hostname if specified,
// or else match all hostnames.
if len(routeHostnames) == 0 {
if len(listenerHostnameVal) > 0 {
return []string{listenerHostnameVal}
}
return []string{"*"} // ← origin of "*"
}
func buildHealthCheckConfig(hc *ir.HealthCheck, ep *ir.DestinationEndpoint) *endpointv3.Endpoint_HealthCheckConfig {
// ...
if hc.Active.HTTP != nil && hc.Active.HTTP.Host != "" { // "*" != "" → true
return nil // skips per-endpoint hostname override
}
// This code is never reached:
if ep == nil || ep.Hostname == nil {
return nil
}
return &endpointv3.Endpoint_HealthCheckConfig{
Hostname: *ep.Hostname,
}
}
The "*" wildcard is not an explicit user-provided hostname — it's an auto-generated default from computeHosts for routes that match by headers only. But buildHealthCheckConfig treats it the same as an intentional hostname override, blocking the per-endpoint path from #8452.
This allows the per-endpoint health_check_config.hostname to be set when the cluster-level host is the wildcard default, while still respecting explicitly configured hostnames.
Verification
With this fix applied:
Cluster-level health check still shows host: "*" (unchanged)
Each endpoint gets health_check_config.hostname set from its Backend endpoint hostname field
Envoy uses the per-endpoint hostname to override the cluster-level "*" for health check requests
Active health checks pass for healthy endpoints, fail for unhealthy ones
Failover works correctly without triggering panic mode
[optional Relevant Links:]
Any extra documentation required to understand the issue.
Description:
Active health check per-endpoint hostname override blocked by wildcard Host: "*"
Summary
When using active HTTP health checks with Backend
FQDN endpointson routes that match by headers (no hostname), the per-endpoint health check hostname override introduced in #8452 does not take effect. The health check Host header is set to "*", causing all endpoints to fail active health checks and triggering envoy panic mode, which is not the purpose of health-check-based failover.Environment
Setup
The HTTPRoute has no hostnames.
Expected Behavior
Each endpoint should have its own Host header in the health check request, derived from the Backend endpoint's hostname field via
Endpoint.HealthCheckConfig.Hostname(the per-endpoint override path added in #8452).Actual Behavior
The health check sends Host:
"*"for all endpoints. The per-endpointhealth_check_configis empty in the xDS config despite the Backend endpoint hostname field being properly populated.This causes:
*)Root Cause
computeHostsreturns"*"when neither theHTTPRoutenor the Listener specifies a hostname:This
"*"is assigned to the IR route at internal/gatewayapi/route.go:1285:"*"hostname is propagated to the health check Host field viaSetHTTPHostIfAbsent:Which calls internal/ir/xds.go:2882-2886:
buildHealthCheckConfigtreats"*"as an explicit hostname override, skipping the per-endpoint path from fix: active health check respect endpoint hostname #8452:The
"*"wildcard is not an explicit user-provided hostname — it's an auto-generated default from computeHosts for routes that match by headers only. But buildHealthCheckConfig treats it the same as an intentional hostname override, blocking the per-endpoint path from #8452.Suggested Fix
One-line change in internal/xds/translator/cluster.go:890:
This allows the per-endpoint
health_check_config.hostnameto be set when the cluster-level host is the wildcard default, while still respecting explicitly configured hostnames.Verification
With this fix applied:
"*"(unchanged)health_check_config.hostnameset from its Backend endpoint hostname field"*"for health check requests[optional Relevant Links:]