Change8

v1.38.0

Breaking Changes
📦 envoyView on GitHub →
5 breaking48 features🐛 5 fixes2 deprecations🔧 62 symbols

Summary

This release introduces extensive new capabilities for dynamic module extensibility, significant enhancements to the MCP and A2A protocols, and security hardening across TLS and authorization components. Several configuration defaults have been tightened, notably around RSA key usage enforcement.

⚠️ Breaking Changes

  • The tcp_proxy configuration now requires explicit setting of `max_early_data_bytes` when `upstream_connect_mode` is not `IMMEDIATE`; missing configurations cause startup validation failure.
  • The on-demand filter no longer performs internal redirects after a successful CDS fetch, meaning earlier filters are not invoked twice. This behavior can be reverted using the runtime feature `envoy.reloadable_features.on_demand_cluster_no_recreate_stream`.
  • The `--define=boringssl=fips` Bazel flag for building BoringSSL/FIPS has been removed; users must now use `--config=boringssl-fips`.
  • The `enforce_rsa_key_usage` option now defaults to `true` for TLS contexts (both upstream and implicitly for general TLS configuration). This option will be removed in the next release.
  • The location of the external processing filter library (`processing_effect_lib`) has moved from `extensions/filters/http/ext_proc` to `extensions/filters/common/processing_effect`.

Migration Steps

  1. If using `upstream_connect_mode` other than `IMMEDIATE` in `tcp_proxy`, ensure `max_early_data_bytes` is explicitly configured.
  2. If relying on the on-demand filter to invoke earlier filters twice after CDS fetch, enable the runtime feature `envoy.reloadable_features.on_demand_cluster_no_recreate_stream`.
  3. Replace the Bazel flag `--define=boringssl=fips` with `--config=boringssl-fips` when building FIPS-enabled binaries.
  4. Review configurations using `enforce_rsa_key_usage` as it now defaults to `true` on upstream TLS contexts; explicitly set it to `false` if required, knowing it will be removed next release.
  5. Update dynamic module code referencing `processing_effect_lib` path from `extensions/filters/http/ext_proc` to `extensions/filters/common/processing_effect`.
  6. If using OAuth2 token encryption, use the runtime guard `disable_token_encryption` to opt-out instead of the removed `oauth2_encrypt_tokens` guard.
  7. Update any code relying on concatenation-based bypasses in RBAC header matchers, as individual value validation is now enforced.
  8. Ensure query parameter mutations using `query_parameter_mutations` are correctly URL-encoded if they contain special characters.
  9. When building with OpenSSL, note that HTTP/3 (QUIC) will be disabled.

✨ New Features

  • New extension points added for dynamic modules: tracers, TLS certificate validators, custom clusters, load balancing policies, input matchers, upstream HTTP-to-TCP bridge, and listener filters with HTTP callouts.
  • Bootstrap extensions now support init-manager integration, drain/shutdown lifecycle hooks, listener-lifecycle callbacks, timer and admin-handler APIs, and metrics support.
  • New network filter callbacks for flow-control and connection state (read_disable, watermarks, half-close, buffer limits) and persistent read/write buffers across callbacks.
  • Listener-filter socket and TLS introspection (SNI, ALPN, JA3/JA4, SSL SANs/subject) plus `write_to_socket`/`close_socket` callbacks enabling protocol negotiation like Postgres SSL and MySQL.
  • Dynamic modules can now be loaded from local file paths and remote HTTP sources (with SHA256 verification, caching, and optional NACK-on-cache-miss).
  • Introduction of process-wide function and shared-data registries for zero-copy cross-module interactions.
  • Rust SDK unified `declare_all_init_functions!` macro for registering various filter types, opt-in `CatchUnwind` panic wrapper, and multi-logger support.
  • Custom metrics support on load balancers with configurable `metrics_namespace`, a fast path `get_host_health_by_address`, and host-membership update callbacks.
  • ABI forward-compatibility ensures modules built against the v1.38 SDK can load in a v1.39 Envoy binary.
  • New `envoy_dynamic_module_callback_is_validation_mode` callback and typed filter-state support.
  • MCP router now supports full method coverage including `resources/list|read|subscribe|unsubscribe`, `resources/templates/list`, `prompts/list|get`, `completion/complete`, `logging/setLevel`, plus notification methods.
  • SSE streaming support added for `tools/call` (pass-through) and fan-out aggregation for `tools/list`, `initialize`, `resources/list`, and `prompts/list`.
  • MCP filter enhancements: HTTP DELETE session termination, relaxed `application/json` Content-Type matching, optional propagation of `traceparent`/`tracestate`/baggage from MCP parameters, and added statistics.
  • New **MCP JSON REST Bridge** HTTP filter (WIP) for transcoding JSON-RPC to REST, including `tools/call` request transcoding.
  • Added parsing support for the **A2A (Agent2Agent)** JSON-RPC protocol.
  • HTTP/2 gained `max_header_field_size_kb` to increase the nghttp2 per-header limit.
  • Optional strict chunked-encoding parsing for HTTP/1 behind a runtime guard.
  • Optional **JSON format for the `x-forwarded-client-cert` (XFCC)** header.
  • New `envoy.filters.http.sse_to_metadata` filter to extract SSE event values into dynamic metadata, supporting pluggable JSON parsing.
  • New `envoy.filters.http.file_server` filter for serving files directly from disk.
  • Refactored `route()`, `clusterInfo()`, and `virtualHost()` to return `OptRef<const T>`, with new `*SharedPtr()` companions.
  • Happy Eyeballs now correctly handles interleaving of non-IP addresses.
  • TLS certificate compression (RFC 8879) extended to include brotli for QUIC, and brotli/zlib for TCP TLS.
  • On-demand upstream certificate fetching via SDS using the `envoy.tls.certificate_selectors.on_demand_secret` extension.
  • Exposed verified issuer SHA-256 fingerprint and serial number via new formatters and Lua accessors.
  • Per-connection SPIFFE trust-domain selection for multi-tenant deployments, with reduced file-watch overhead and support for `watched_directory`.
  • Ext_authz gained `shadow_mode` (decision written to filter state without terminating requests), `path_override`, honoring `status_on_error` on 5xx failures, and a fix for propagating headers from denied responses.
  • OAuth2 gained per-route configuration, support for `TLS_CLIENT_AUTH` (RFC 8705 mTLS client auth), clearing of `OauthExpires` cookie on logout.
  • RBAC header matcher now validates each header value individually to prevent bypasses.
  • Query-parameter values added via `query_parameter_mutations` are now URL-encoded.
  • OpenSSL can be used as an alternative to BoringSSL (build with `--config=openssl`).
  • New observability formatters: `SPAN_ID`, `QUERY_PARAMS`, `UPSTREAM_LOCAL_CLOSE_REASON`, `DOWNSTREAM_LOCAL_CLOSE_REASON`, `UPSTREAM_DETECTED_CLOSE_TYPE`, `DOWNSTREAM_DETECTED_CLOSE_TYPE`, `%UPSTREAM_HOSTS_ATTEMPTED%` and related ID formatters, `%FILE_CONTENT(...)%`, `%SECRET(name)%`.
  • `*_WITHOUT_PORT` address formatters now accept an optional `MASK_PREFIX_LEN` for CIDR masking.
  • Prometheus admin endpoint supports the **protobuf exposition format** and **Prometheus native histograms**.
  • Added cluster-level and listener-level stats matchers, plus stats-scope metric-count limits.
  • OpenTelemetry stat sink can export metrics over **HTTP** (OTLP/HTTP).
  • Access loggers gained stats customization and gauge support in the stats access logger, network filters can register as access loggers, new `asn_org` geoip field, and log events on OpenTelemetry spans.
  • Load-balancer rebuilds are coalesced during EDS batch host updates, reducing CPU spikes.
  • Added Passive degraded-host detection (`detect_degraded_hosts`) via the `x-envoy-degraded` response header.
  • Redis Cluster zone-aware routing support (`LOCAL_ZONE_AFFINITY` / `LOCAL_ZONE_AFFINITY_REPLICAS_AND_PRIMARY`).
  • New `upstream_rq_active_overflow` counter to distinguish active-RQ saturation from pending-queue saturation.
  • Fix for ODCDS over ADS on tcp_proxy; SRDS late-listener init fix; drop_overload now uses cached EDS.
  • EDS metadata comparison now uses a cached hash for O(1) per-host comparison.
  • ORCA weight manager defaults to preferring named metrics over application utilization.
  • Rate limiting gained `is_negative_hits` on `hits_addend` to refund tokens.
  • New `RemoteAddressMatch` rate-limit action supporting CIDR matching, inversion, and formatter substitution.
  • Per-descriptor `x-ratelimit-*` response headers and shadow mode in the local rate limit filter.
  • `timeout: 0s` in HTTP ext_authz and HTTP rate-limit filters now correctly means "no timeout".

🐛 Bug Fixes

  • The nghttp2 **CVE-2026-27135** vulnerability has been patched in HTTP/2.
  • Fix for propagating headers from denied responses in ext_authz.
  • Fix for ODCDS over ADS when using tcp_proxy.
  • Fix for SRDS late-listener initialization.
  • Fix where drop_overload now correctly uses cached EDS.

Affected Symbols

⚡ Deprecations

  • The `--define=boringssl=fips` flag is deprecated and removed in favor of `--config=boringssl-fips`.
  • The `oauth2_encrypt_tokens` runtime guard is removed; token encryption is now the default behavior, with opt-out available via `disable_token_encryption`.