1.37.0 (Pending)

Incompatible behavior changes

Changes that are expected to cause an incompatibility if applicable; deployment changes are likely required

  • dynamic modules: The dynamic module ABI has been updated to support streaming body manipulation. This change also fixed potential incorrect behavior when access or modify the request or response body. See https://github.com/envoyproxy/envoy/issues/40918 for more details.

  • server: Added container-aware CPU detection on Linux that respects cgroup CPU limits in addition to hardware thread count and CPU affinity. This change only affects behavior when the --concurrency flag is not explicitly set. Envoy now uses the minimum of hardware threads, CPU affinity, and cgroup CPU limits to determine the number of worker threads by default. This provides better resource utilization in containerized environments (Docker, Kubernetes) where CPU limits are set via cgroups. The new behavior is enabled by default and can be disabled by setting the ENVOY_CGROUP_CPU_DETECTION environment variable to false. When disabled, Envoy will fall back to the previous behavior of using only hardware thread count and CPU affinity for worker thread calculation. Uses conservative rounding (floor) to account for non-worker threads and prevent container throttling, which may reduce the total number of connections.

Minor behavior changes

Changes that may cause incompatibilities for some users, but should not for most

  • ext_authz: Check that the response header count is less than the configured limits before applying mutations, and do not add new headers if not.

  • ext_proc: Use one of a hard-coded set of error messages when a HeaderMutation fails. Removing request-specific details allows grouping by similar failure types. Detailed messages remain available in debug logs.

  • mobile: Use mobile specific network observer registries to propagate network change signals. This behavior can be reverted by setting the runtime guard envoy.reloadable_features.mobile_use_network_observer_registry.

  • quic: Switch to use QUICHE provided migration logic to handle port migration upon path degrading and migration to Server Preferred Address. This behavior can be reverted by setting envoy.reloadable_features.use_migration_in_quiche.

  • router: Added host_rewrite to RouteAction to support substitution formatting for host header rewriting. Added path_rewrite to RouteAction to support substitution formatting for path header rewriting.

Bug fixes

Changes expected to improve the state of the world and are unlikely to have negative effects

  • bootstrap: Fixed an issue where the custom header_prefix would result in a crash at startup.

  • composite: Fixed per-route configuration for composite filter to support matching on response headers and trailers. Previously, per-route matchers would silently fail when attempting to match on HttpResponseHeaderMatchInput or HttpResponseTrailerMatchInput, causing the delegated filter to be skipped without error.

  • connection pool: Fixed a crash in the TCP connection pool that occurs during downstream connection teardown when large requests or responses trigger flow control.

  • dns: c-ares resolver: add optional reinit_channel_on_timeout to reinitialize the resolver after DNS timeouts.

  • http: Fixed shouldDrainConnectionUponCompletion() to properly send GOAWAY frames for HTTP/2 and HTTP/3 instead of aggressively closing connections. This prevents response body transmission interruption and ERR_DRAINING errors on the client side. HTTP/1.1 behavior remains unchanged.

  • http2: Fixed a bug where Envoy would leak memory if an HTTP/2 stream was reset before request headers were sent. For example, if an upstream HTTP filter sent a local reply after the connection was established but before request headers were sent, the memory allocated for the stream was not released.

  • http2: Optimized HTTP/2 header processing by avoiding memory allocations and string copies for well-known header names. For common HTTP/2 headers (such as :method, :path, :status, content-type, user-agent, etc.), Envoy now references static strings instead of copying header names. This reduces memory allocations and improves performance for typical HTTP/2 traffic.

  • lua: Fixed a bug where Lua filters could cause Envoy to crash when setting the response body to a payload larger than the body buffer limit.

  • router: Fixed a regression where router-set headers (e.g., x-envoy-expected-rq-timeout-ms, x-envoy-attempt-count) were not accessible in request_headers_to_add configuration on the initial request. Headers configured via request_headers_to_add can now reference router-set headers using formatters like %REQ(x-envoy-expected-rq-timeout-ms)%.

  • tap: Add the missing conversion support to ensure tapped message are correctly handled for multi-event submissions.

  • udp_proxy: Fixed a few areas where the addresses might be moved from the data packet being processed.

Removed config or runtime

Normally occurs at the end of the deprecation period

  • http: Removed runtime guard envoy.reloadable_features.http1_balsa_allow_cr_or_lf_at_request_start and legacy code paths.

  • http: Removed runtime guard envoy.reloadable_features.original_src_fix_port_exhaustion and legacy code paths.

  • jwt_authn: Removed runtime guard envoy.reloadable_features.jwt_fetcher_use_scheme_from_uri and legacy code paths.

  • quic: Removed runtime guard envoy.reloadable_features.http3_remove_empty_cookie and legacy code paths.

  • tcp: Removed runtime guard envoy.reloadable_features.tcp_proxy_retry_on_different_event_loop and legacy code paths.

  • xds: Removed runtime guard envoy.reloadable_features.report_load_with_rq_issued and legacy code paths.

New features

  • access_log: Support process-level rate limiting on access log emission by ProcessRateLimitFilter.

  • admin: Added /memory/tcmalloc admin endpoint that provides TCMalloc memory statistics.

  • cel: Added per-expression configuration options for CEL evaluator to control string conversion, concatenation, and string extension functions. CEL expressions in RBAC policies and access logger filters can now enable string functions such as replace() and split() through the new cel_config and cel_config fields in their respective configurations. See CelExpressionConfig for details.

  • dns_filter: Added access_log for DNS filter.

  • ext_authz: Add a new configuration field to the http ext authz filter enforce_response_header_limits that allows admins to enable / disable the behavior of dropping response headers once the header map count / size constraints have been reached.

  • formatter: Added support for the following new access log formatters: - %REQUEST_HEADER(X?Y):Z% as full name version of %REQ(X?Y):Z% - %RESPONSE_HEADER(X?Y):Z% as full name version of %RESP(X?Y):Z% - %RESPONSE_TRAILER(X?Y):Z% as full name version of %TRAILER(X?Y):Z% This provides a more consistent naming scheme for users to understand and use.

  • generic_proxy: Added custom substitution format specifiers support in the tracing custom tags of the generic_proxy filter. Now the %REQUEST_PROPERTY%, %RESPONSE_PROPERTY% etc. can be used in the value field for generic proxy.

  • http: Added vhost_header to RouteConfiguration, allowing use of a different header for vhost matching.

  • http2: Added new parameter to the sendGoAwayAndClose to support gracefully closing of HTTP/2 connection.

  • logging: Added support for the not-equal operator in access log filter rules, in ComparisonFilter.

  • lua: Added drainConnectionUponCompletion() to the Lua filter stream info API. This allows Lua scripts to mark connections for draining, which adds a Connection: close header for HTTP/1.1 or sends a GOAWAY frame for HTTP/2 and HTTP/3.

  • metrics_service: Added batch_size configuration to the Metrics Service to allow batching metrics into multiple gRPC messages. When set to a positive value, metrics will be batched with at most batch_size metric families per message. This helps avoid hitting gRPC message size limits (typically 4MB) when sending large numbers of metrics. If not set or set to 0, all metrics will be sent in a single message, preserving the current behavior.

  • network: Added a change to start populating the filter state envoy.network.network_namespace when a connection is accepted on a listener with network_namespace_filepath configured. This provides read-only access to the network namespace for filters, access logs, and other components.

  • otlp_stat_sink: Added support for dropping stats via DropAction during custom metric conversion.

  • overload management: The fixed heap resource monitor can now calculate memory pressure as currently allocated memory divided by maximum heap size, giving more accurate and lower memory pressure values. This can avoid unnecessary load shedding or overload actions. To enable, set envoy.reloadable_features.fixed_heap_use_allocated to true. The default algorithm (heap_size - pageheap_unmapped - pageheap_free) does not discount for free memory in TCMalloc caches.

  • quic: Added QUIC protocol option max_sessions_per_event_loop to limit the maximum number of new QUIC sessions created per event loop. The default is 16, preserving the previous hardcoded limit.

  • redis: Added cluster-scoped command support with a flexible response handling framework.

  • tracing: Added new value field and the substitution format specifier could be used to extract values from various parts of the request/response for custom tags.

  • udp_sink: Enhanced the UDP sink to support tapped messages larger than 64 KB.

  • wasm: Added sign foreign function to create cryptographic signatures. See Wasm foreign functions for more details.

  • xds: Added runtime guard envoy.reloadable_features.report_load_when_rq_active_is_non_zero. When enabled, LRS continues to send locality_stats reoprt to config server when there is no request_issued in the poll cycle.