This episode dives into listeners and filter chains: HTTP connection manager configuration, virtual hosts, path matching, header manipulation, redirect, and rewrite, complete with routes you can try right away.

The hello world configuration from episode 3 is still raw: every path is forwarded to one cluster. Episode 4 changes that. We'll dive into listener, filter chain, and route configuration — how to map multiple domains and paths to different clusters, and how to manipulate requests with headers, redirects, and rewrites.
This is the episode where Envoy starts to feel like a real router. You'll see how a single config file can handle multiple virtual hosts at once, and how match rules work from the most specific to the most general.
A listener is the gateway for all traffic. An example listener with two filter chains (HTTP and TCP) will be dissected later in episode 8, but for now focus on a single HTTP filter chain:
listeners:
- name: listener_http
address:
socket_address:
address: 0.0.0.0
port_value: 10000
filter_chains:
- filters:
- name: envoy.filters.network.http_connection_manager
typed_config:
"@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
stat_prefix: api_gateway
route_config:
name: api_routes
virtual_hosts: []
http_filters:
- name: envoy.filters.http.router
typed_config:
"@type": type.googleapis.com/envoy.extensions.filters.http.router.v3.RouterNotice stat_prefix: api_gateway — this value sets the prefix for all metrics produced by this listener. Choosing clear prefixes makes it easy to distinguish metrics between listeners in the admin interface.
filter_chains defines the sequence of filters for one type of connection (for example HTTP only).route_config holds the virtual host and route definitions.http_filters is the HTTP filter pipeline that processes requests, and router must always be the last filter.Virtual hosts let a single listener serve many domains at once. The following example maps two domains to different clusters:
route_config:
name: api_routes
virtual_hosts:
- name: backend_vh
domains:
- api.example.com
routes:
- match:
prefix: "/orders"
route:
cluster: orders_service
- name: web_vh
domains:
- www.example.com
routes:
- match:
prefix: "/"
route:
cluster: web_serviceEnvoy selects a virtual host based on the Host header of the request. The domain api.example.com is sent to orders_service, while www.example.com goes to web_service. The virtual host api.example.com is chosen only if the Host header matches exactly.
Three common ways to match paths:
exact: "/health" — only the path that is exactly the same.prefix: "/api/" — any path starting with a given string.safe_regex — an allowed regex pattern for advanced matching.Evaluation order matters: Envoy checks routes in the order they appear in the YAML, so place the most specific rules first.
Sometimes a backend doesn't accept the same path the client requested. Use prefix_rewrite:
routes:
- match:
prefix: "/api/v1"
route:
cluster: orders_service
prefix_rewrite: "/v1"With prefix_rewrite: "/v1", the request /api/v1/users is changed to /v1/users before being forwarded to the backend. This technique is very common for hiding internal API structure.
If you want to tell clients to move to another URL:
routes:
- match:
prefix: "/old"
redirect:
path_redirect: "/new"
response_code: 301The redirect configuration returns a 301 response with the location /new without touching the backend. Redirects suit migrating old endpoints.
Envoy can add, modify, or remove headers at both the virtual host and route levels:
virtual_hosts:
- name: web_vh
domains:
- www.example.com
request_headers_to_add:
- header:
key: X-Envoy-Gateway
value: "v1"
append_action: ADD_IF_ABSENT
routes:
- match:
prefix: "/"
route:
cluster: web_servicerequest_headers_to_add adds the header X-Envoy-Gateway with the value v1 to every request entering this virtual host. append_action: ADD_IF_ABSENT ensures the header isn't duplicated if it already exists.
Headers are Envoy's main communication tool with upstreams and clients. To see the headers arriving at the backend, run a backend that prints headers:
curl -v -H "Host: www.example.com" http://localhost:10000/ 2>&1 | grep "^> "Lines starting with > show the request headers Envoy sends to the backend. The curl -v command is the fastest way to observe header manipulation results in this episode.
Episode 4 took your routing to the next level: listeners with the HTTP connection manager, virtual hosts for many domains, exact and prefix matching, rewrites and redirects, and per-request header manipulation.
Key takeaways:
Host header.exact, prefix, or safe_regex to match paths.prefix_rewrite changes the path before the backend; redirect tells clients to move URLs.request_headers_to_add adds headers per virtual host or route.router always stays as the last HTTP filter in the pipeline.In the next episode, episode 5, we'll discuss clusters and load balancing — cluster and endpoint definitions, round robin, least request, ring hash, and maglev policies, plus health checks, connection pools, and outlier detection.