.. _version_history_1.39.0: 1.39.0 (Pending) ================= Minor behavior changes ---------------------- *Changes that may cause incompatibilities for some users, but should not for most* * **golang**: Reduced the per-cgo-call mutex acquisition on the Golang HTTP filter by making the ``has_destroyed_`` flag a ``std::atomic``. CAPI methods whose only Envoy-side work is Filter-owned or runs on the worker thread (``setHeader``, ``removeHeader``, ``setTrailer``, ``removeTrailer``, ``addData``, ``injectData``, ``continueStatus``, ``sendLocalReply``, ``setBufferHelper``, ``copyBuffer``, ``drainBuffer``, ``setUpstreamOverrideHost``, ``clearRouteCache``, ``setDynamicMetadata``, ``setStringFilterState``) no longer take the mutex, eliminating an uncontended atomic compare-and-swap pair on every such call. The mutex is retained on the CAPI methods that inline-dereference Envoy-stream-owned objects from off-thread (``getHeader``, ``copyHeaders``, ``copyTrailers``, ``getIntegerValue``, ``setDrainConnectionUponCompletion``) where it serialises against ``onDestroy`` to prevent the worker thread from freeing the underlying header map or ``StreamInfo`` mid-access, and on the five methods that write to the per-request ``strValue`` scratch buffer (``getStringValue``, ``getDynamicMetadata``, ``getStringFilterState``, ``getStringProperty``, ``getSecret``). * **http2**: The GOAWAY load shed point is fixed to use a graceful two-phase shutdown sequence, to avoid risk to client traffic. This behavioral change can be temporarily reverted by setting runtime guard ``envoy.reloadable_features.http2_fix_goaway_loadshed_point`` to ``false``. * **router**: The upstream transport failure reason (e.g. TLS certificate validation errors) is no longer included in the HTTP response body sent to downstream clients. It remains available in access logs via ``%UPSTREAM_TRANSPORT_FAILURE_REASON%``. This behavioral change can be temporarily reverted by setting runtime guard ``envoy.reloadable_features.hide_transport_failure_reason_in_response_body`` to ``false``. This is being changed because in many cases the upstream failure details are inappropriate to send to the downstream client as it discloses too many internal details. * **stats**: Optimized prometheus stats endpoint. Users should see a roughly 30-40% latency improvement in calls to the endpoint for cases where the scrape results in lots of cluster stats. There should be no visible changes to users, or incompatibilities. * **tls**: ``SslSocket`` now reports ``ECONNRESET`` as ``ConnectionReset`` by reading the system error code from BoringSSL's error queue, matching ``RawBufferSocket`` behavior. When a connection is closed with ``ConnectionCloseType::AbortReset``, ``SslSocket`` also skips the TLS ``close_notify`` shutdown so the peer reliably observes a TCP RST instead of racing a graceful close against the reset. This behavioral change can be temporarily reverted by setting runtime guard ``envoy.reloadable_features.ssl_socket_report_connection_reset`` to ``false``. Bug fixes --------- *Changes expected to improve the state of the world and are unlikely to have negative effects* * **build**: Fixed ``Illegal ambiguous match`` error when building contrib targets with ``--config=aws-lc-fips`` on aarch64 by restricting the ``using_aws_lc`` branch of ``SELECTED_CONTRIB_EXTENSIONS`` to ``linux_x86_64``. Mirrors the approach taken by #32382 for ``boringssl_fips``. * **build**: Fixed ``Illegal ambiguous match`` error when building contrib targets with ``--config=boringssl-fips`` on aarch64 by restricting the ``using_boringssl_fips`` branch of ``SELECTED_CONTRIB_EXTENSIONS`` to ``linux_x86_64``. Mirrors the approach taken by #44661 for ``aws-lc``. * **dns_resolver**: Fixed a UAF in the Hickory DNS resolver where the dispatcher lambda posted by the Rust-thread completion callback captured a raw pointer to the resolver. If the resolver was destroyed before the dispatcher drained the lambda, dereferencing the pointer was undefined behavior. The lambda now captures a ``std::weak_ptr`` and locks it before touching the resolver. * **dns_resolver**: Fixed a memory leak in the Hickory DNS resolver where ``ActiveDnsQuery::cancel()`` did not free the pending query state or decrement the ``pending_resolutions`` gauge. Cancelled queries now release their shell object, Rust-side query box, and gauge tick synchronously, matching the contract followed by the c-ares and Apple DNS resolvers. * **dns_resolver**: Fixed macOS build failure (#45061) for the Hickory DNS resolver by linking Apple's ``SystemConfiguration`` framework. The framework is required by the ``system-configuration`` crate that ``hickory-resolver`` pulls in via its ``system-config`` feature. * **dynamic_modules**: Fixed a bug where the HTTP filter per-route configuration and the upstream HTTP TCP bridge configuration did not handle the ``google.protobuf.Struct`` configuration message as the API definition requires. Both factories now serialize the ``Struct`` to a JSON string and pass the string to the dynamic module side as the configuration, matching the behavior already in place for every other dynamic module extension factory. * **dynamic_modules**: Fixed a crashing bug in the HTTP filter when a stream was already above the downstream write-buffer high watermark at filter-chain construction time. Downstream watermark callback registration is now deferred until the in-module filter has been constructed. * **http**: Fixed a bug where an upstream HTTP/2 or HTTP/3 ``RST_STREAM(NO_ERROR)`` received after a complete response would cause the response to be discarded and replaced with an error. This behavior is common with some gRPC clients and servers, but is often intermittent. This behavior can be temporarily reverted by setting the runtime flag ``envoy.reloadable_features.http_preserve_rst_no_error`` to ``false``. * **load_report**: Fixed a bug in load stats reporting where reports were dropped if only custom metrics or completed requests were present in a reporting interval. This behavioral change can be reverted by setting the runtime guard ``envoy.reloadable_features.report_load_for_non_zero_stats`` to ``false``. * **oauth2**: Fixed a crash in the OAuth2 filter where AES-CBC decryption of token cookies could spuriously succeed (~1/256) when the configured HMAC secret did not match the secret used to encrypt the cookie (for example after secret rotation, or when receiving legacy unencrypted tokens). The resulting binary "plaintext" was written back into the ``Cookie:`` request header and tripped a ``HeaderString`` validation assert. Such plaintexts are now rejected and the original cookie value is preserved, matching the behavior already documented for the explicit decryption-failure case. * **rbac**: Fixed a bug in the :ref:`mTLS Authenticated ` principal extension where if an invalid SAN matcher was configured, it would incorrectly match any certificate in the allowed trust chain. Known bad configurations are an invalid ``OID`` when using an ``OTHER_NAME``, or specifying a ``StringMatcher`` with an invalid configuration. * **spiffe_validator**: Fixed a bug where if an invalid custom SAN matcher was configured it would later lead to a crash when validating a certificate. * **wasm**: Fixed a bug where Envoy did not recreate the Wasm VM when only :ref:`environment_variables ` changed in ``vm_config``. The VM was previously reused from the cache because environment variables were not included in the vm_key computation. New features ------------ * **access_log**: Added ``%UPSTREAM_SERVER_NAME%`` access log formatter returning the SNI from the established upstream TLS connection. * **access_log**: Supported the singleton stats scope in the :ref:`stats access logger `. * **attributes**: Added ``upstream.server_name`` CEL attribute returning the SNI from the established upstream TLS connection. * **composite**: Added support for the :ref:`inline matcher ` in the composite HTTP filter. Now users could specify the matcher inline in the filter configuration instead of using the :ref:`ExtensionWithMatcher ` filter. * **dynamic_modules**: Added ``envoy_dynamic_module_callback_cluster_lb_context_get_filter_state_bytes`` and ``envoy_dynamic_module_callback_cluster_lb_context_get_filter_state_typed`` ABI callbacks so that a dynamic-module cluster's load balancer can read filter state set by an upstream HTTP filter (or any other producer) when picking a host. The Rust SDK exposes these as ``ClusterLbContext::get_filter_state_bytes`` and ``ClusterLbContext::get_filter_state_typed``. * **dynamic_modules**: Added ``envoy_dynamic_module_callback_is_validation_mode`` ABI callback that allows dynamic modules to check if the server is running in config validation mode. * **http_inspector**: Enabled Balsa parser for HTTP inspector by default. This behavior can be temporarily reverted by setting the runtime guard ``envoy.reloadable_features.http_inspector_use_balsa_parser`` to ``false``. This runtime guard will be removed in a future release of Envoy. * **http_inspector**: Enabled Balsa parser for HTTP inspector by default. This behavior can be temporarily reverted by setting the runtime guard ``envoy.reloadable_features.http_inspector_use_balsa_parser`` to ``false``. This runtime guard will be removed in a future release of Envoy. * **jwt_authn**: Added :ref:`verification_status_header ` to the ``ExtractOnlyWithoutValidation`` requirement. When a JWT is present in the request but fails signature verification, the named request header (default ``x-jwt-signature-verified``) is set to ``false`` so downstream filters (RBAC, ext_authz) can distinguish forwarded-but-unverified claims from validated ones. The header is not set on a successfully verified JWT or when no JWT is present. This behavior can be reverted by setting the runtime guard ``envoy.reloadable_features.jwt_authn_add_verification_status_header`` to ``false``. * **logging**: Added ``%N`` as a custom spdlog pattern flag that emits the Envoy version string. It can be used in the ``--log-format`` CLI flag or the bootstrap ``application_log_config.log_format`` to include the running version in every log line, e.g. ``--log-format "[%N][%l] %v"``. * **mysql_proxy**: Added SSL termination support to the MySQL proxy filter with RSA-mediated ``caching_sha2_password`` authentication. The filter can now terminate downstream TLS connections using the :ref:`starttls transport socket ` and transparently mediate MySQL 8.0+ ``caching_sha2_password`` full authentication by performing RSA public key exchange on behalf of the client. Added a new :ref:`downstream_ssl ` config option with ``DISABLE``, ``REQUIRE``, and ``ALLOW`` modes. * **quic**: Added support for TLS session ticket resumption in QUIC using configured session ticket keys from :ref:`session_ticket_keys `. This enables faster reconnection across server instances by allowing clients to resume TLS sessions without full handshakes. The feature is disabled by default and can be enabled by setting runtime guard ``envoy.reloadable_features.quic_session_ticket_support`` to ``true``. * **ratelimit**: Make namespace for storing rate limit service response metadata configurable. * **resource_monitors**: Overload manager fixed heap resource monitor now supports :ref:`max_heap_size_bytes_runtime ` for runtime-overridable max heap size (e.g. RTDS or ``/runtime_modify``). * **router**: Added :ref:`refresh_cluster_on_retry ` to :ref:`retry policies ` so retry attempts can refresh the route-selected upstream cluster before being sent. This enables cross-cluster retries for dynamic cluster selection such as the :ref:`matcher cluster specifier `. * **router**: Added support for ``refreshRouteCluster`` on weighted cluster routes. When a filter calls ``refreshRouteCluster()``, the weighted cluster entry will select a different cluster from the configured pool, avoiding previously-tried clusters within the same request. Once all clusters have been tried, the selection pool resets so that any cluster may be chosen again. This enables filters to implement per-attempt cluster failover across weighted clusters without replacing the entire route. * **set_metadata_filter**: Added :ref:`per-route configuration support ` to the ``set_metadata`` HTTP filter. * **stat_sinks**: Added :ref:`max_data_points_per_request ` configuration to the OpenTelemetry stat sink to chunk metric export requests. * **stat_sinks**: Added a new :ref:`WASM stats filter ` contrib extension (``envoy.stat_sinks.wasm_filter``) that acts as programmable middleware between the metrics snapshot and any inner stats sink. A user-supplied WASM plugin can: filter metrics by index, inject global tags from node metadata (``stats_filter_set_global_tags``), rename metrics (``stats_filter_set_name_overrides``), inject synthetic counters/gauges (``stats_filter_inject_metrics``), and filter histograms (``stats_filter_get_histograms``). This enables moving centralized metric processing logic (tag enrichment, name rewriting, custom metric injection) into the proxy itself. Configured via :ref:`WasmFilterStatsSinkConfig `. * **tcp_proxy**: Added :ref:`check_drain_close ` to the TCP proxy filter to close downstream connections with ``FlushWrite`` when the drain manager requests drain close during downstream read or write handling. * **tcp_proxy**: Added ``envoy.reloadable_features.tcp_proxy_delay_route_selection`` to delay selecting a route until just before the upstream connection is established. The selection moment depends on the value of :ref:`upstream_connect_mode`. * **tls**: Added substitution commands ``%DOWNSTREAM_TLS_GROUP%`` and ``%UPSTREAM_TLS_GROUP%``. The TLS group may be used to discern if a TLS connection used a post quantum safe key exchange (e.g. X25519MLKEM768).