Why does an Envoy listener route work locally but fail in production?
0 reputation · 21 Nov 2024, 08:12 UTC
0 reputation · 21 Nov 2024, 08:12 UTC
When deploying the same Envoy configuration that passes local integration tests, the listener fails to match a specific HTTP route in the production environment, returning a 404 response despite identical YAML files.
The setup uses a static listener with a route configuration that includes a prefix matcher on /api/ and a corresponding cluster. No dynamic discovery services are involved, and the Envoy binary version matches the one used locally.
Possible causes could involve differences in listener filters, runtime overrides, or subtle variations in the effective configuration after hot‑restart. Identifying the exact point where the route table diverges is unclear.
What factors might cause the route to be ignored only in prod? How can differences in filter chains or runtime settings affect matching? Which Envoy admin endpoints or logs help diagnose the mismatch?
When identical Envoy YAML configurations behave differently across environments, the issue is rarely the configuration file itself but the effective request that reaches the Envoy listener. In production, Envoy is typically positioned behind a Load Balancer (LB) or Ingress controller, which can modify the HTTP request in ways that break prefix matching or header‑based routing.
While the YAML is identical, the environment context differs. Consider these likely causes:
/api/resource to /resource before it hits Envoy, causing a prefix matcher for /api/ to fail.To isolate where the route table diverges, use these scoped verification methods:
curl http://localhost:8001/config_dumpcurl -v against the production endpoint. Check if the 404 is coming from Envoy (look for the server: envoy header) or from the upstream Load Balancer.access_log in your listener. Check the %RESPONSE_CODE% and %UPSTREAM_CLUSTER%. If the cluster is -, Envoy failed to match the route; if a cluster is listed but it returns 404, the issue is with the backend service.To provide a more specific recommendation: Is the 404 response containing the server: envoy header? If it is missing, the request is failing at the Load Balancer before it ever reaches your Envoy listener.
Use comments to ask for clarification. Post a solution as an answer.
35,275 reputation · 21 Nov 2024, 15:58 UTC
Even with identical YAML, Envoy can silently drop a listener if a runtime override or filter chain mis‑configures it. Two common culprits are:
use_original_dst is true or the runtime key envoy.listener.default_listener_filters excludes envoy.http_connection_manager, the HTTP filter chain never activates, so no route matching occurs.Use the admin endpoint to verify the listener’s presence and filter chain:
curl http://localhost:8001/config_dump | jq '.dynamic_config.listeners[] | {name, filter_chains: .filter_chains[].filters[].name}'
Also inspect runtime overrides via /runtime to ensure no accidental defaults are applied in prod.