Envoy Proxy Knowledge Patch
Load this skill when changing Envoy configuration, extending Envoy, or
investigating behavior that may have shifted across recent releases.
Start with the upgrade notes below. Then open only the topic references needed
for the configuration or code under review.
Reference index
| Reference |
Topics |
| Upgrades, builds, and operations |
Removed guards and extensions, build toolchains, process defaults, admin controls, workers, file watching |
| HTTP routing and filters |
HTTP codecs, routing, matching, rewrites, filter chains, header mutation, compression, custom responses |
| Authentication and security |
OAuth2, JWT, API keys, credentials, RBAC, identity metadata, hardening |
| External processing and authorization |
ext-proc, ext-authz, processor lifecycle, failure policies, mutations |
| TLS, QUIC, and networking |
TLS, certificates, QUIC, listeners, TCP, UDP, PROXY protocol, sockets, namespaces |
| Discovery, DNS, and load balancing |
xDS, SDS, RDS, resolvers, DNS caches, clusters, endpoints, host and LB selection |
| Extensions, Lua, Wasm, and dynamic modules |
Extension APIs, Lua, Wasm, Go plugins, composite filters, native modules |
| Observability and formatting |
Access logs, formatters, tracing, metrics, taps, exporters, diagnostics |
| Resilience, rate limits, and overload |
Rate limits, retries, overload actions, resource monitors, health checks, outlier detection |
| Application protocols and data filters |
Redis, Valkey, PostgreSQL, MySQL, gRPC, GeoIP, Thrift, SSE, MCP |
Upgrade blockers and irreversible migrations
Do not rely on expired rollback guards
Many behavior changes initially shipped with runtime guards and later removed
their legacy paths. Before prescribing a rollback, check
upgrades-build-and-operations.md
for the guard's removal and then check the owning topic reference.
In particular:
- Explicit internal-address behavior became mandatory after its rollback guard
was removed. Configure
internal_address_config; do not assume RFC1918
addresses are internal.
- The old HTTP/2 propagation, streaming-shadow, RDS normalization, xDS-copy,
and empty-host dynamic-forward-proxy paths have also lost their rollback
guards.
- OAuth2 cookie encryption can no longer be disabled with
envoy.reloadable_features.oauth2_encrypt_tokens; only the filter's explicit
trusted-environment plaintext mode remains.
- The old TCP-proxy idle-timer behavior is gone.
Remove deleted extensions before startup
Configuration still naming a removed extension fails at load time.
- Replace the deleted
grpc_credentials/aws_iam extension.
- Remove the contrib Squash HTTP filter.
- Remove OpenCensus tracing configuration.
- Review every removed-runtime-control list before copying old runtime files.
Update source-build automation
- Build extension code as C++20.
- Use the supported compiler configurations instead of the removed
clang-libstdc++ setup.
- Use
--config=boringssl-fips for FIPS builds.
- Bazel 8 source builds retain WORKSPACE mode only with
--enable_workspace --noenable_bzlmod; account for the changed external
runfiles layout.
- Treat
--config=openssl as a constrained build: it disables HTTP/3 and is
outside the stated security-policy coverage.
Treat TLS enforcement as mandatory
Peer RSA certificate keyUsage is always enforced. The old
enforce_rsa_key_usage option is ignored, so fix incompatible certificates
instead of trying to turn validation off. Also account for TLS Inspector's
ClientHello version checks and the rejection of empty trusted-CA material.
Security-critical configuration checks
Migrate OAuth2 cookies in the safe order
For the AES-256-GCM migration:
- Enable
envoy.reloadable_features.oauth2_use_gcm_encryption.
- Wait until every instance can read
gcm. cookies.
- Confirm
oauth_legacy_cbc_decrypt has fallen to zero.
- Disable
envoy.reloadable_features.oauth2_legacy_cbc_decrypt_compat.
Reversing the order invalidates newly issued cookies. Leaving CBC fallback
enabled retains the vulnerable path. Review the full OAuth2 sequence in
authentication-and-security.md.
Bound dynamic-forward-proxy destinations
Use DnsCacheConfig.resolved_address_filter to remove disallowed CIDR ranges
from DNS answers. For defense in depth, apply the upstream RBAC filter after
host selection and default-deny unwanted upstream_ip_port values.
Avoid disclosing transport failures
Do not restore upstream transport failure details to downstream response
bodies. Diagnose with %UPSTREAM_TRANSPORT_FAILURE_REASON% in controlled logs
instead.
Recheck repeated-header policy
HeaderMatcher evaluates separately encoded header values individually.
CEL and generic matcher inputs still see comma-joined values. Audit policy
that depended on joined strings.
High-impact default changes
Size HTTP/2 explicitly
Safer HTTP/2 defaults cap concurrent streams at 1024, the initial stream
window at 16MiB, and the connection window at 24MiB. Set intentional
values after measuring workload needs instead of retaining the temporary
legacy-default guard.
Cookie reassembly participates in request-header limits. A separate cookie
limit and an nghttp2 Rapid Reset token bucket are configurable.
Review parser and protocol limits
- HTTP Inspector uses Balsa by default.
- JSON parsing is capped at 1,000 nesting levels.
- Oversized combined PROXY-protocol TLVs are removed.
- HTTP/3 pseudo-headers are validated.
- Strict HTTP/1 chunk parsing remains opt-in.
Account for effective sampling
The tap filter and tap transport socket now honor tap_enabled before their
match predicate. OpenTelemetry tracing gives Envoy's request-entry decision,
including overall_sampling, precedence over incoming and tracer-level
sampling signals.
Revalidate worker and socket sizing
Unset Linux worker concurrency considers hardware threads, CPU affinity, and
cgroup CPU limits. io_uring now applies default write-watermark backpressure.
Use worker CPU affinity and listener CPU-locality balancing only after checking
reuse-port and process-affinity assumptions.
Common implementation recipes
External processing
- Choose HTTP or gRPC transport intentionally.
- Select buffered, streamed, or
FULL_DUPLEX_STREAMED body handling based on
mutation and failure semantics.
- Set
failure_mode_allow, status_on_error, and per-route overrides
deliberately.
- Treat gRPC-client creation as a processor failure; fail-open no longer means
silently ignoring startup failure.
- When chaining processors, account for state updates and
Content-Length.
See external processing and authorization
for lifecycle, local replies, processing effects, and network controls.
External authorization
- Use per-route backend selection and retry policy where needed.
- Validate mutated request and response header limits.
- Bound denial bodies and decide whether denied headers may reach clients.
- Use shadow mode for evaluation without enforcement.
- For UDP, authorize when the session is created.
Routing and request mutation
- Refresh route or cluster selection after writing routing-relevant filter
state.
- Use body-aware on-demand recreation only when filters can replay safely.
- Apply formatter-backed host, path, redirect, and direct-response rewrites
with explicit trust boundaries.
- Test matcher changes with dynamic metadata and repeated headers.
- When delaying TCP route selection, set early-data and drain behavior
explicitly.
DNS and cluster selection
- Prefer typed DNS-cluster configuration over deprecated direct cluster DNS
fields.
- Recheck resolver inheritance when a DNS cache or filter has empty local
resolver configuration.
- Use DNS-layer address filtering plus post-selection authorization for
dynamic destinations.
- Expect EDS hostname-only changes to recreate hosts and drain pools.
- Use
refresh_cluster_on_retry only when a dynamically selected cluster can
safely change between attempts.
Native dynamic modules
Check extension-family and callback coverage before implementing a module.
Loading supports local paths and digest-verified remote artifacts; cache
misses and fetch failures differ. Validate callback signatures and isolation.
Use
extensions-lua-wasm-and-modules.md
for request, worker, listener, network, bootstrap, load-balancer, transport,
health-check, formatter, stats-sink, and filter-state APIs.
Rate limiting and overload
timeout: 0s means no timeout for HTTP rate limit and ext-authz.
- A local token bucket with
max_tokens: 0 rejects every match.
- Negative hits refill budget; shadow mode evaluates without enforcing.
- Retry budgets can include requests from a configured interval.
- Fixed-heap maximums can be runtime-adjusted.
- Treat connection-pool, HTTP/2 dispatch, stream flush, idle HTTP/3, and
high-watermark closures as separate load-shed mechanisms.
Diagnostic workflow
- Identify the owning subsystem and open its reference from the index.
- Search the exact field, extension name, formatter, runtime guard, or stat.
- If a guard is suggested, verify it was not removed in the upgrade
reference.
- Separate default changes from opt-in features and disabled-by-default
guards.
- For extensions, check both configuration API changes and callback ABI
changes.
- For traffic-policy changes, test request, response, retry, local-reply, and
stream-close paths independently.
- For security migrations, stage changes so every instance can read both old
and new state before disabling compatibility.
- Prefer observability fields and counters over exposing diagnostic details
to downstream clients.
Configuration review checklist
- Removed fields, extensions, and runtime guards are absent.
- TLS secrets are non-empty and key usage is compatible.
- OAuth2 redirect domains, cookie attributes, token forwarding, and encryption
migration state are explicit.
- Dynamic destinations are constrained before and after DNS resolution.
- Header-count, header-size, cookie, body, metadata, and JSON-depth limits are
intentional.
- ext-proc and ext-authz failure, timeout, retry, and shadow behavior are
explicit.
- Route-cache or route-cluster refresh occurs after relevant state mutation.
- Listener namespaces, socket options, keepalive, and connection watermarks
match the deployment platform.
- Load-shed actions have corresponding metrics and capacity tests.
- Access logs avoid secrets while retaining controlled transport and identity
diagnostics.
1---2name: envoy-knowledge-patch-23description: Envoy Proxy4license: MIT5---678# Envoy Proxy Knowledge Patch910Load this skill when changing Envoy configuration, extending Envoy, or11investigating behavior that may have shifted across recent releases.1213Start with the upgrade notes below. Then open only the topic references needed14for the configuration or code under review.15## Reference index1617| Reference | Topics |18| --- | --- |19| [Upgrades, builds, and operations](references/upgrades-build-and-operations.md) | Removed guards and extensions, build toolchains, process defaults, admin controls, workers, file watching |20| [HTTP routing and filters](references/http-routing-and-filters.md) | HTTP codecs, routing, matching, rewrites, filter chains, header mutation, compression, custom responses |21| [Authentication and security](references/authentication-and-security.md) | OAuth2, JWT, API keys, credentials, RBAC, identity metadata, hardening |22| [External processing and authorization](references/external-processing-and-authorization.md) | ext-proc, ext-authz, processor lifecycle, failure policies, mutations |23| [TLS, QUIC, and networking](references/tls-quic-and-networking.md) | TLS, certificates, QUIC, listeners, TCP, UDP, PROXY protocol, sockets, namespaces |24| [Discovery, DNS, and load balancing](references/discovery-dns-and-load-balancing.md) | xDS, SDS, RDS, resolvers, DNS caches, clusters, endpoints, host and LB selection |25| [Extensions, Lua, Wasm, and dynamic modules](references/extensions-lua-wasm-and-modules.md) | Extension APIs, Lua, Wasm, Go plugins, composite filters, native modules |26| [Observability and formatting](references/observability-and-formatting.md) | Access logs, formatters, tracing, metrics, taps, exporters, diagnostics |27| [Resilience, rate limits, and overload](references/resilience-rate-limits-and-overload.md) | Rate limits, retries, overload actions, resource monitors, health checks, outlier detection |28| [Application protocols and data filters](references/application-protocols-and-data-filters.md) | Redis, Valkey, PostgreSQL, MySQL, gRPC, GeoIP, Thrift, SSE, MCP |2930## Upgrade blockers and irreversible migrations3132### Do not rely on expired rollback guards3334Many behavior changes initially shipped with runtime guards and later removed35their legacy paths. Before prescribing a rollback, check36[upgrades-build-and-operations.md](references/upgrades-build-and-operations.md)37for the guard's removal and then check the owning topic reference.3839In particular:4041- Explicit internal-address behavior became mandatory after its rollback guard42 was removed. Configure `internal_address_config`; do not assume RFC191843 addresses are internal.44- The old HTTP/2 propagation, streaming-shadow, RDS normalization, xDS-copy,45 and empty-host dynamic-forward-proxy paths have also lost their rollback46 guards.47- OAuth2 cookie encryption can no longer be disabled with48 `envoy.reloadable_features.oauth2_encrypt_tokens`; only the filter's explicit49 trusted-environment plaintext mode remains.50- The old TCP-proxy idle-timer behavior is gone.5152### Remove deleted extensions before startup5354Configuration still naming a removed extension fails at load time.5556- Replace the deleted `grpc_credentials/aws_iam` extension.57- Remove the contrib Squash HTTP filter.58- Remove OpenCensus tracing configuration.59- Review every removed-runtime-control list before copying old runtime files.6061### Update source-build automation6263- Build extension code as C++20.64- Use the supported compiler configurations instead of the removed65 `clang-libstdc++` setup.66- Use `--config=boringssl-fips` for FIPS builds.67- Bazel 8 source builds retain WORKSPACE mode only with68 `--enable_workspace --noenable_bzlmod`; account for the changed external69 runfiles layout.70- Treat `--config=openssl` as a constrained build: it disables HTTP/3 and is71 outside the stated security-policy coverage.7273### Treat TLS enforcement as mandatory7475Peer RSA certificate `keyUsage` is always enforced. The old76`enforce_rsa_key_usage` option is ignored, so fix incompatible certificates77instead of trying to turn validation off. Also account for TLS Inspector's78ClientHello version checks and the rejection of empty trusted-CA material.7980## Security-critical configuration checks8182### Migrate OAuth2 cookies in the safe order8384For the AES-256-GCM migration:85861. Enable `envoy.reloadable_features.oauth2_use_gcm_encryption`.872. Wait until every instance can read `gcm.` cookies.883. Confirm `oauth_legacy_cbc_decrypt` has fallen to zero.894. Disable `envoy.reloadable_features.oauth2_legacy_cbc_decrypt_compat`.9091Reversing the order invalidates newly issued cookies. Leaving CBC fallback92enabled retains the vulnerable path. Review the full OAuth2 sequence in93[authentication-and-security.md](references/authentication-and-security.md).9495### Bound dynamic-forward-proxy destinations9697Use `DnsCacheConfig.resolved_address_filter` to remove disallowed CIDR ranges98from DNS answers. For defense in depth, apply the upstream RBAC filter after99host selection and default-deny unwanted `upstream_ip_port` values.100101### Avoid disclosing transport failures102103Do not restore upstream transport failure details to downstream response104bodies. Diagnose with `%UPSTREAM_TRANSPORT_FAILURE_REASON%` in controlled logs105instead.106107### Recheck repeated-header policy108109`HeaderMatcher` evaluates separately encoded header values individually.110CEL and generic matcher inputs still see comma-joined values. Audit policy111that depended on joined strings.112113## High-impact default changes114115### Size HTTP/2 explicitly116117Safer HTTP/2 defaults cap concurrent streams at `1024`, the initial stream118window at `16MiB`, and the connection window at `24MiB`. Set intentional119values after measuring workload needs instead of retaining the temporary120legacy-default guard.121122Cookie reassembly participates in request-header limits. A separate cookie123limit and an nghttp2 Rapid Reset token bucket are configurable.124125### Review parser and protocol limits126127- HTTP Inspector uses Balsa by default.128- JSON parsing is capped at 1,000 nesting levels.129- Oversized combined PROXY-protocol TLVs are removed.130- HTTP/3 pseudo-headers are validated.131- Strict HTTP/1 chunk parsing remains opt-in.132133### Account for effective sampling134135The tap filter and tap transport socket now honor `tap_enabled` before their136match predicate. OpenTelemetry tracing gives Envoy's request-entry decision,137including `overall_sampling`, precedence over incoming and tracer-level138sampling signals.139140### Revalidate worker and socket sizing141142Unset Linux worker concurrency considers hardware threads, CPU affinity, and143cgroup CPU limits. io_uring now applies default write-watermark backpressure.144Use worker CPU affinity and listener CPU-locality balancing only after checking145reuse-port and process-affinity assumptions.146147## Common implementation recipes148149### External processing150151- Choose HTTP or gRPC transport intentionally.152- Select buffered, streamed, or `FULL_DUPLEX_STREAMED` body handling based on153 mutation and failure semantics.154- Set `failure_mode_allow`, `status_on_error`, and per-route overrides155 deliberately.156- Treat gRPC-client creation as a processor failure; fail-open no longer means157 silently ignoring startup failure.158- When chaining processors, account for state updates and `Content-Length`.159160See [external processing and authorization](references/external-processing-and-authorization.md)161for lifecycle, local replies, processing effects, and network controls.162163### External authorization164165- Use per-route backend selection and retry policy where needed.166- Validate mutated request and response header limits.167- Bound denial bodies and decide whether denied headers may reach clients.168- Use shadow mode for evaluation without enforcement.169- For UDP, authorize when the session is created.170171### Routing and request mutation172173- Refresh route or cluster selection after writing routing-relevant filter174 state.175- Use body-aware on-demand recreation only when filters can replay safely.176- Apply formatter-backed host, path, redirect, and direct-response rewrites177 with explicit trust boundaries.178- Test matcher changes with dynamic metadata and repeated headers.179- When delaying TCP route selection, set early-data and drain behavior180 explicitly.181182### DNS and cluster selection183184- Prefer typed DNS-cluster configuration over deprecated direct cluster DNS185 fields.186- Recheck resolver inheritance when a DNS cache or filter has empty local187 resolver configuration.188- Use DNS-layer address filtering plus post-selection authorization for189 dynamic destinations.190- Expect EDS hostname-only changes to recreate hosts and drain pools.191- Use `refresh_cluster_on_retry` only when a dynamically selected cluster can192 safely change between attempts.193194### Native dynamic modules195196Check extension-family and callback coverage before implementing a module.197Loading supports local paths and digest-verified remote artifacts; cache198misses and fetch failures differ. Validate callback signatures and isolation.199200Use201[extensions-lua-wasm-and-modules.md](references/extensions-lua-wasm-and-modules.md)202for request, worker, listener, network, bootstrap, load-balancer, transport,203health-check, formatter, stats-sink, and filter-state APIs.204205### Rate limiting and overload206207- `timeout: 0s` means no timeout for HTTP rate limit and ext-authz.208- A local token bucket with `max_tokens: 0` rejects every match.209- Negative hits refill budget; shadow mode evaluates without enforcing.210- Retry budgets can include requests from a configured interval.211- Fixed-heap maximums can be runtime-adjusted.212- Treat connection-pool, HTTP/2 dispatch, stream flush, idle HTTP/3, and213 high-watermark closures as separate load-shed mechanisms.214215## Diagnostic workflow2162171. Identify the owning subsystem and open its reference from the index.2182. Search the exact field, extension name, formatter, runtime guard, or stat.2193. If a guard is suggested, verify it was not removed in the upgrade220 reference.2214. Separate default changes from opt-in features and disabled-by-default222 guards.2235. For extensions, check both configuration API changes and callback ABI224 changes.2256. For traffic-policy changes, test request, response, retry, local-reply, and226 stream-close paths independently.2277. For security migrations, stage changes so every instance can read both old228 and new state before disabling compatibility.2298. Prefer observability fields and counters over exposing diagnostic details230 to downstream clients.231232## Configuration review checklist233234- Removed fields, extensions, and runtime guards are absent.235- TLS secrets are non-empty and key usage is compatible.236- OAuth2 redirect domains, cookie attributes, token forwarding, and encryption237 migration state are explicit.238- Dynamic destinations are constrained before and after DNS resolution.239- Header-count, header-size, cookie, body, metadata, and JSON-depth limits are240 intentional.241- ext-proc and ext-authz failure, timeout, retry, and shadow behavior are242 explicit.243- Route-cache or route-cluster refresh occurs after relevant state mutation.244- Listener namespaces, socket options, keepalive, and connection watermarks245 match the deployment platform.246- Load-shed actions have corresponding metrics and capacity tests.247- Access logs avoid secrets while retaining controlled transport and identity248 diagnostics.