1.36.0 (Pending)
Incompatible behavior changes
Changes that are expected to cause an incompatibility if applicable; deployment changes are likely required
ext_proc: Reverted #39740 to re-enable
fail_open
+FULL_DUPLEX_STREAMED
configuration combination.http: A route refresh will now result in a tracing refresh. The trace sampling decision and decoration of the new route will be applied to the active span. This change can be reverted by setting the runtime guard
envoy.reloadable_features.trace_refresh_after_route_refresh
tofalse
. Note, if pack_trace_reason is set totrue
(it istrue
by default), a request marked as traced cannot be unmarked as traced after the tracing refresh.
Minor behavior changes
Changes that may cause incompatibilities for some users, but should not for most
dns_filter: Honor the default DNS resolver configuration in the bootstrap config typed_dns_resolver_config if the client_config is empty.
ext_proc: If failure_mode_allow is true, save the gRPC failure status code returned from the ext_proc server in the filter state. Previously, all fail-open cases would return
call_status
Grpc::Status::Aborted
.generic_proxy: Generic proxy codec adds the same buffer limit as the connection buffer limit. If the buffer limit is exceeded, the connection is disconnected. This behavior can be reverted by setting the runtime guard
envoy.reloadable_features.generic_proxy_codec_buffer_limit
tofalse
.http: Added accounting for decompressed HTTP header bytes sent and received. Existing stats only count wire-encoded header bytes. This can be accessed through the
%UPSTREAM_DECOMPRESSED_HEADER_BYTES_RECEIVED%
,%DOWNSTREAM_DECOMPRESSED_HEADER_BYTES_RECEIVED%
,%UPSTREAM_DECOMPRESSED_HEADER_BYTES_SENT%
, and the%DOWNSTREAM_DECOMPRESSED_HEADER_BYTES_SENT%
access log command operators.http3: Turn off HTTP/3 happy eyeballs in upstream via runtime guard
envoy.reloadable_features.http3_happy_eyeballs
. It was found to favor TCP over QUIC when UDP does not work on IPv6 but works on IPv4.mobile: Explicitly drain connections upon network change events regardless of whether the DNS cache is refreshed or not. This behavior can be reverted by setting the runtime guard
envoy.reloadable_features.decouple_explicit_drain_pools_and_dns_refresh
tofalse
.oauth2: Added response code details to
401
local responses generated by the OAuth2 filter.tap: Previously, streamed trace buffered data was only flushed when it reached the configured size. If the threshold was never met, the data remained buffered until the connection was closed. With this change, buffered data will be flushed proactively. Specifically, if the buffer does not reach the configured size but has been held for more than 15 seconds, it will be sent immediately.
testing: In test code for external extensions, matchers
Http::HeaderValueOf
,HasHeader
, andHeaderHasValueRef
must be replaced withContainsHeader
. Any uses of matcherHeaderHasValue(...)
should be replaced with::testing::Pointee(ContainsHeader(...))
.websocket: Allow 4xx and 5xx to go through the filter chain for websocket handshake response check, and the behavior can be disabled by the runtime guard
envoy.reloadable_features.websocket_allow_4xx_5xx_through_filter_chain
.
Bug fixes
Changes expected to improve the state of the world and are unlikely to have negative effects
aws: Added missing session name, session duration, and
external_id
parameters in AssumeRole credentials provider.dns: Fixed a use-after-free (UAF) in DNS cache that can occur when the
Host
header is modified between the Dynamic Forwarding Proxy and Router filters.formatter: Fixed a bug where the
%TRACE_ID%
command cannot work properly at the header mutations.geoip: Fixed a bug in the MaxMind provider where the
found_entry
field in the lookup result was not checked before trying to populate headers with data. If this field is not checked the provider could try to populate headers with wrong data, as per the documentation for the MaxMind library libmaxminddb.md.http: Fixed a bug where the
response_headers_to_add
may be processed multiple times for the local responses from the router filter.http: Fixed a bug where the premature resets of streams may result in the recursive draining and potential stack overflow. Setting proper
max_concurrent_streams
value for HTTP/2 or HTTP/3 could eliminate the risk of the stack overflow before this fix.http3: Fixed a bug where access log gets skipped for HTTP/3 requests when the stream is half closed. This behavior can be reverted by setting the runtime guard
envoy.reloadable_features.quic_fix_defer_logging_miss_for_half_closed_stream
tofalse
.listeners: Fixed issue where TLS inspector listener filter timed out when used with other listener filters. The bug was triggered when a previous listener filter processed more data than the TLS inspector had requested, causing the TLS inspector to incorrectly calculate its buffer growth strategy. The fix ensures that buffer growth is now based on actual bytes available rather than the previously requested amount.
oauth2: Fixed a bug introduced in PR [#40228](https://github.com/envoyproxy/envoy/pull/40228), where OAuth2 cookies were removed for requests matching the
pass_through_matcher
configuration. This broke setups with multiple OAuth2 filter instances using differentpass_through_matcher
configurations, because the first matching instance removed the OAuth2 cookies–even when a passthrough was intended–impacting subsequent filters that still needed those cookies.oauth2: Fixed an issue where cookies prefixed with
__Secure-
or__Host-
were not receiving aSecure
attribute.release: Fix distroless image to ensure nonroot.
stats: Fixed a bug where the metric name
expiration_unix_time_seconds
ofcluster.<cluster_name>.ssl.certificate.<cert_name>.<metric_name>
andlistener.<address>.ssl.certificate.<cert_name>.<metric_name>
was not being properly extracted in the final Prometheus stat name.udp_proxy: Fixed a crash in the UDP proxy that occurred during
ENVOY_SIGTERM
when active tunneling sessions were present.
Removed config or runtime
Normally occurs at the end of the deprecation period
balsa: Removed runtime guard
envoy.reloadable_features.wait_for_first_byte_before_balsa_msg_done
and legacy code paths.dfp: Removed runtime guard
envoy.reloadable_features.dfp_fail_on_empty_host_header
and legacy code paths.dispatcher: Removed runtime guard
envoy.restart_features.fix_dispatcher_approximate_now
and legacy code paths.dns: Removed runtime guard
envoy.reloadable_features.prefer_ipv6_dns_on_macos
and legacy code paths.dns_resolver: Removed runtime guard
envoy.reloadable_features.getaddrinfo_num_retries
and legacy code paths.dynamic_forward_proxy: Removed runtime guard
envoy.reloadable_features.avoid_dfp_cluster_removal_on_cds_update
and legacy code paths.gcp_authn: Removed runtime guard
envoy.reloadable_features.gcp_authn_use_fixed_url
and legacy code paths.geoip_providers: Removed runtime guard
envoy.reloadable_features.mmdb_files_reload_enabled
and legacy code paths.http: Removed runtime guard
envoy.reloadable_features.allow_alt_svc_for_ips
and legacy code paths.http: Removed runtime guard
envoy.reloadable_features.filter_chain_aborted_can_not_continue
and legacy code paths.http: Removed runtime guard
envoy.reloadable_features.local_reply_traverses_filter_chain_after_1xx
and legacy code paths.http: Removed runtime guard
envoy.reloadable_features.proxy_104
and legacy code paths.http: Removed runtime guard
envoy.reloadable_features.proxy_status_mapping_more_core_response_flags
and legacy code paths.http: Removed runtime guard
envoy.reloadable_features.use_filter_manager_state_for_downstream_end_stream
and legacy code paths.http3: Removed runtime guard
envoy.reloadable_features.http3_remove_empty_trailers
and legacy code paths.http_connection_manager: Removed runtime guard
envoy.reloadable_features.explicit_internal_address_config
and legacy code paths.jwt_authn: Removed runtime guard
envoy.reloadable_features.jwt_authn_remove_jwt_from_query_params
and legacy code paths.jwt_authn: Removed runtime guard
envoy.reloadable_features.jwt_authn_validate_uri
and legacy code paths.network: Removed runtime guard
envoy.reloadable_features.udp_socket_apply_aggregated_read_limit
and legacy code paths.oauth2: Removed runtime guard
envoy.reloadable_features.oauth2_use_refresh_token
and legacy code paths.proxy_filter: Removed runtime guard
envoy.reloadable_features.proxy_ssl_port
and legacy code paths.proxy_protocol: Removed runtime guard
envoy.reloadable_features.use_typed_metadata_in_proxy_protocol_listener
and legacy code paths.quic: Removed runtime guard
envoy.reloadable_features.prefer_quic_client_udp_gro
and legacy code paths.quic: Removed runtime guard
envoy.reloadable_features.report_stream_reset_error_code
and legacy code paths.rds: Removed runtime guard
envoy.reloadable_features.normalize_rds_provider_config
and legacy code paths.router: Removed runtime guard
envoy.reloadable_features.shadow_policy_inherit_trace_sampling
and legacy code paths.router: Removed runtime guard
envoy.reloadable_features.streaming_shadow
and legacy code paths.stats: Removed runtime guard
envoy.reloadable_features.enable_include_histograms
and legacy code paths.udp_proxy: Removed runtime guard
envoy.reloadable_features.enable_udp_proxy_outlier_detection
and legacy code paths.upstream: Removed runtime guard
envoy.reloadable_features.use_config_in_happy_eyeballs
and legacy code paths.xds: Removed runtime guard
envoy.reloadable_features.xds_prevent_resource_copy
and legacy code paths.
New features
cel: Added a new
%TYPED_CEL%
formatter command that, unlike%CEL%
, can output non-string values (number, boolean, null, etc.) when used in formatting contexts that accept non-string values, such as json_format. The new command is introduced so as to not break compatibility with the existing command’s behavior.composite: Allow composite filter to be configured to insert a filter into the filter chain outside of the decode headers lifecycle phase.
dns_filter, redis_proxy and prefix_matcher_map: Switch to using Radix Tree instead of Trie for performance improvements.
dynamic_modules: Added a new Logging ABI that allows modules to emit logs in the standard Envoy logging stream under “dynamic_modules” ID. In the Rust SDK, they are available as
envoy_log_info
, etc.dynamic_modules: Added support for counters, gauges, histograms, and their vector variants to the dynamic modules API.
ext_authz: Added support for per-route gRPC service override in the
ext_authz
HTTP filter. This allows different routes to use different external authorization backends by configuring a grpc_service in the per-routecheck_settings
. Routes without this configuration continue to use the default authorization service.geoip: Added a new metric
db_build_epoch
to track the build timestamp of the MaxMind geolocation database files. This can be used to monitor the freshness of the databases currently in use by the filter. See MaxMind DB build_epoch for more details.header_to_metadata: Added optional statistics collection for the Header-To-Metadata filter. When the stat_prefix field is configured, the filter emits detailed counters for rule processing, metadata operations, etc. See Header-To-Metadata filter statistics for details.
health_check: Added support for request payloads in HTTP health checks. The
send
field inHttpHealthCheck
can now be used to specify a request body to be sent during health checking. This feature supports both hex-encoded text and binary payloads, similar to TCP health checks. The payload can only be used with HTTP methods that support request bodies (POST
,PUT
,PATCH
,OPTIONS
). Methods that must not have request bodies (GET
,HEAD
,DELETE
,TRACE
) are validated and will throw an error if combined with payloads. The implementation is optimized to process the payload once during configuration and reuse it for all health check requests. See HttpHealthCheck for configuration details.http: Added stream_flush_timeout to allow for configuring a stream flush timeout independently from the stream idle timeout.
http: Added
upstream_rq_per_cx
histogram to track requests per connection for monitoring connection reuse efficiency.load_reporting: Added support for endpoint-level load stats and metrics reporting. Locality load reports now include per endpoint statistics and metrics, but only for endpoints with updated stats, optimizing report size and efficiency.
lua: Added
route()
to the Stream handle API, allowing Lua scripts to retrieve route information. So far, the only method implemented ismetadata()
, allowing Lua scripts to access route metadata scoped to the specific filter name. See Route object API for more details.lua: Added
virtualHost()
to the Stream handle API, allowing Lua scripts to retrieve virtual host information. So far, the only method implemented ismetadata()
, allowing Lua scripts to access virtual host metadata scoped to the specific filter name. See Virtual host object API for more details.lua: Added a new
filterState()
onstreamInfo()
which provides access to filter state objects stored during request processing. This allows Lua scripts to retrieve string, boolean, and numeric values stored by various filters for use in routing decisions, header modifications, and other processing logic. See Filter State API for more details.observability: Added
ENVOY_NOTIFICATION
macro to track specific conditions in production environments.otlp_stat_sink: Added support for resource attributes. The stat sink will use the resource attributes configured for the OpenTelemetry tracer via resource_detectors.
overload management: Added load shed point
envoy.load_shed_points.http2_server_go_away_and_close_on_dispatch
that sendsGOAWAY
and closes connections for HTTP/2 server processing of requests. When aGOAWAY
frame is submitted by this load shed point, the counterhttp2.goaway_sent
will be incremented.quic: Added new option to support base64 encoded server ID in QUIC-LB.
ratelimit: Added the rate_limits field to generate rate limit descriptors. If this field is set, the VirtualHost.rate_limits or RouteAction.rate_limits fields will be ignored. However, RateLimitPerRoute.rate_limits will take precedence over this field.
rbac: Switch the IP matcher to use LC-Trie for performance improvements.
redis: Added support for
GEOSEARCH
andGETEX
.router: Added request_body_buffer_limit and request_body_buffer_limit configuration fields to enable buffering of large request bodies beyond connection buffer limits.
router_check_tool: Added support for testing routes with dynamic metadata matchers in the router check tool. The tool now accepts a
dynamic_metadata
field in test input to set metadata that can be matched by route configuration. This allows comprehensive testing of routes that depend on dynamic metadata for routing decisions.socket: Added
network_namespace_filepath
to SocketAddress. This field allows specifying a Linux network namespace filepath for socket creation, enabling network isolation in containerized environments.stats: Added support to remove unused metrics from memory for extensions that support evictable metrics. This is done periodically during the metric flush.
tap: Add record_upstream_connection to determine whether upstream connection information is recorded in the HTTP buffer trace output.
tcp_proxy: Added support for generating and propagating a request ID on synthesized upstream HTTP requests when tunneling requests. It can be configured using request_id_extension.
tls_inspector: Added dynamic metadata when failing to parse the
ClientHello
.tracing: Added trace_context_option enum in the Zipkin tracer config. When set to
USE_B3_WITH_W3C_PROPAGATION
, the tracer will: extract trace information from W3C trace headers when B3 headers are not present (downstream), and inject both B3 and W3C trace headers for upstream requests to maximize compatibility. The default valueUSE_B3
maintains backward compatibility with B3-only behavior.tracing: Enhanced Zipkin tracer with advanced collector configuration via collector_service using HttpService. New features include:
Custom HTTP Headers: Add headers to collector requests for custom metadata, service identification, and collector-specific routing.
Full URI Parsing: The
uri
field now supports both path-only (/api/v2/spans
) and full URI formats (https://zipkin-collector.example.com/api/v2/spans
). When using full URIs, Envoy automatically extracts hostname and path components - hostname sets the HTTPHost
header, and path sets the request path. Path-only URIs fallback to using cluster name as hostname.
When configured, collector_service takes precedence over legacy configuration fields (collector_cluster, collector_endpoint, collector_hostname), which will be deprecated in a future release. Legacy configuration does not support custom headers or URI parsing.