Upgrading to ATS v10.2

This section covers changes when upgrading from Traffic Server v10.1 to v10.2. If you are upgrading from v9.x, read Upgrading to ATS v10.x below as well, since all of those changes apply too.

TLS Session Resumption

Inbound TLS sessions are now bound to the SNI they were issued under and to that SNI’s verify_client policy from sni.yaml, including the trust anchors the client certificate was verified against. A session ticket or session ID offered under a different SNI, after the policy for its SNI changed, or after those trust anchors were replaced, is no longer resumed and completes a full handshake instead. Replacing the bundle named by proxy.config.ssl.CA.cert.filename takes effect on the next traffic_ctl config reload, which is also when a replaced bundle begins to apply to fresh handshakes. Clients that key their session caches by hostname, which includes browsers and curl, are unaffected. Sessions issued by a previous release may not resume after the upgrade and complete a full handshake instead. See Mututal TLS for details.

Security Hardening

A series of security fixes changed defaults and tightened validation. Many of them refuse traffic, or reject configuration, that earlier releases accepted, so review this section before upgrading. Where a fix has a published CVE identifier it is noted inline; refer to the security advisory for this release for the full set of identifiers, severities and affected version ranges.

This section covers only changes with operator-visible effect. The same work included a larger number of memory-safety and bounds fixes – use-after-free, out-of-bounds access, integer overflow and stack-allocation fixes across the core, the protocol stacks and the plugins – which change no behavior a configuration can observe and are not listed individually.

Changed Defaults

  • ip_allow.yaml now ships outbound rules that deny CONNECT tunnels to unspecified, loopback, private, link-local and IPv4-mapped IPv6 destination addresses. If a deployment intentionally proxies CONNECT to one of those ranges, add a more specific apply: out allow rule before the deny rule: the first matching range determines the outcome.

  • proxy.config.http2.default_buffer_water_mark now defaults to 32768 instead of -1, and its accepted range is now 1024 to 4294967295. A configuration that explicitly set this to -1, or to any value below 1024, is no longer valid and must be updated or removed.

  • The tsmemcache plugin now binds only to the loopback address by default. It previously bound the wildcard address, which exposed the Traffic Server cache to every host able to reach the port. To bind a specific address, pass it as the second plugin argument, and read the security notes in Memcache Plugin first.

  • Two settings that were previously accepted unchecked are now range checked, so a configuration carrying an out-of-range value fails to load rather than being silently clamped or overflowing. Their defaults are unchanged. proxy.config.http.header_field_max_size accepts 0 to 65535, and proxy.config.hostdb.round_robin_max_count accepts 1 to 1024.

Stricter Request and Response Validation

Each of the following refuses a message earlier releases would have processed. The common theme is framing that can be read two ways.

  • A HEAD request carrying Content-Length or Transfer-Encoding is rejected. Set proxy.config.http.reject_head_with_content to 0 to restore the previous behavior.

  • A Transfer-Encoding whose final coding is not chunked is rejected, as is any Transfer-Encoding appearing in HTTP/2 or HTTP/3 request headers, where the field has no meaning.

  • Chunked parsing is stricter in two further ways: a bare LF terminating a chunked trailer is rejected under strict parsing, and a chunk extension quoted-string value containing CR or LF is rejected (CVE-2026-24033).

  • A header field longer than the 16-bit field-length limit is rejected rather than silently truncated to its low 16 bits. A Host header longer than its buffer is likewise bounded rather than overrunning it (CVE-2026-33930).

  • A response that cannot be parsed is refused whatever status it claims. Earlier releases relayed a 302 carrying a Location header even when parsing its header block failed; that exemption keyed only off the status code and never accounted for why the parse failed. The responses a broken origin actually depends on resolve as a completed parse and are unaffected.

  • A URL whose port is outside the 16-bit range is rejected, and response status code parsing is bounded rather than allowed to overflow. An IPv6 literal with an out-of-range hextet is rejected where it was previously accepted, which can affect a configuration file carrying a malformed address.

  • Body preclusion for CONNECT now applies only to successful responses, so an error response to a CONNECT is framed by its own headers.

  • HTTP/2 and HTTP/3 header decoding enforces a per-field size limit, rejects oversized HPACK indexes and rejects integers that overflow during XPACK decoding. CONTINUATION accumulation that would overflow the header block length is rejected. Outstanding HTTP/2 SETTINGS frames are bounded, and an unnecessary SETTINGS frame closes the connection.

  • HTTP/2 Content-Length is compared against the payload length at full width, so a mismatch cannot be hidden by truncation.

  • HTTP/2 origin trailers are no longer forwarded to HTTP/1 clients, which cannot frame them.

Headers Now Removed

  • Client-supplied headers whose name begins with @ are stripped before any plugin hook runs, in both directions (CVE-2026-33267). @ headers are Traffic Server internal, and accepting one from a client let a request set state a plugin would read as Traffic Server’s own. A plugin that relied on reading a client-supplied @ header will no longer see it. The log line reporting a strip is throttled, so a client sending them in volume does not flood the diagnostics.

  • Headers named in the Connection field are removed per RFC 9110 section 7.6.1, rather than being forwarded to the next hop.

Proxy Protocol

  • A PROXY v1 header whose port is out of range is rejected.

  • A PROXY header carrying no addresses is handled rather than assumed to carry them, including on TLS connections.

Access Control Corrections

These rules now apply as written. Re-check any configuration that relies on them.

  • Nonstandard method matching in remap ACL filtering applies as written.

  • The client SNI action test in SNI_IpAllow applies as written.

  • Loop detection is retained on outbound-transparent ports.

Connection Reuse and TLS

  • An inbound TLS session is bound to the SNI and verify_client policy that issued it, so a session offered outside that scope completes a full handshake instead of resuming. See TLS Session Resumption above. This supersedes the narrower check that rejected a resumed session presenting no client certificate where the matching sni.yaml entry required one; that check is retained as a last line of defense and is normally unreachable.

  • Reusing a pooled outbound session requires that its client certificate match the one the current transaction would present, so a transaction cannot inherit another’s authenticated identity. HTTP/2 origin certificates are likewise verified on session reuse.

  • A server session is not returned to the pool while unread bytes remain on it, so a later request cannot be answered from another transaction’s leftover response data. Related to this, an origin connection owed an unsent request body is closed rather than pooled, including under Expect: 100-continue (CVE-2025-31699), and the unread body of an Expect: 100-continue POST is no longer forwarded as a new request (CVE-2025-55702).

  • The outbound server_name SNI policy is validated before use, and the bytes it names are owned across a configuration reload rather than referenced into a freed configuration.

Origin Selection

  • parent.config retries are capped at one per window, so a parent that is failing cannot be retried repeatedly within the same window.

Plugins

  • origin_server_auth strips client-supplied x-amz- request headers that fall outside the scope its signature covers, rather than forwarding headers the signature does not authenticate.

  • magick requires a signing key and allowlists the convert operators it will run. An existing configuration without a signing key will not load.

  • esi bounds nested ESI comments and request length, and validates esi:include URLs before fetching them.

  • certifier rejects SNI names that are unsafe to use as a filename, rather than deriving a path from them.

  • Several plugins now bound input they previously accepted without limit, so an input larger than the bound is refused instead of being processed: webp_transform bounds both the buffered body and the ImageMagick decode, stale_response caps its buffering, xdebug caps the X-Remap header to the buffer content, multiplexer rejects oversized chunks, and url_sig requires the delimiter in its C= parameter.

  • combo_handler rejects an empty Content-Type when an allowlist is configured; compress stops the transform after a deflate() error rather than continuing; prefetch constrains relative paths; rate_limit no longer allows the queue to be bypassed.

  • Regex rules that drive a security or routing decision can be required to match the whole subject. This is off by default. See proxy.config.regex.anchor_policy_rules and Writing Secure Regex Rules for the call sites it covers, the config-load report that names each pattern it would change, and the rewrites that preserve behavior. regex_map in remap.config and fqdn in sni.yaml already require a whole-subject match and are unaffected by the setting (CVE-2026-22068).

Changes in 10.2.1

These are the behavior changes in 10.2.1 that are not security hardening. The security-related ones, including the new reject_head_with_content default, are under Security Hardening and TLS Session Resumption above.

  • JA4 fingerprints change. ja4_fingerprint and jax_fingerprint now hash the client’s signature algorithms into the last section of the fingerprint, as the JA4 specification requires, hex-encode ALPN bytes that are not alphanumeric, and report the correct version code for SSL 2.0. The last section of almost every fingerprint differs from 10.2.0, so stored fingerprints, and any allow or deny rules built from them, must be regenerated.

  • compress sends a weak ETag (W/"abc") for a compressed response and adds Vary to cached client responses. A client holding a compressed copy can still revalidate with If-None-Match, but If-Match and If-Range compare strongly and no longer match it. See Compress Plugin.

  • TLS session ticket keys follow the global ticket key configuration for every certificate context, and for a dest_ip certificate they are derived from that certificate, so a ticket issued for one certificate is not accepted for another. Tickets issued by 10.2.0 may not resume after the upgrade and complete a full handshake. A context whose keys cannot be bound to a certificate neither issues nor accepts tickets, counted by proxy.process.ssl.total_tickets_no_certificate.

  • With proxy.config.http.allow_half_open set to 0, a client that aborts before the origin has sent its response header again tears down the origin connection. Since 10.1 it was held open until the response arrived.

  • When proxy.config.http.cache.try_compat_key_read is enabled, a legacy object is revalidated without conditional headers so the full response is stored under the current key, and invalidations are sent to both keys. Plan for the extra origin transfer on first revalidation.

  • hrw4u exits 1 when any input fails to compile, where it previously exited 0. Build scripts that ignored the status will now fail. Its sandbox policy also applies to more spellings than before, so a configuration that passed with a deny list on 10.2.0 may now be rejected.

  • ts::Metrics no longer has an iterator; see the API note later in this section.

  • New configuration: proxy.config.http.per_server.connection.metric_aggregate and proxy.config.http.per_server.connection.metric_prefix, alongside the documented proxy.config.http.per_server.connection.metric_enabled. With metric_enabled set and metric_aggregate at its default of 0, behavior is unchanged; values 2 and 3 stop publishing the per group metrics for match type both.

Incompatible Changes

The following change alters existing behavior. It is included deliberately, as a bug fix: the previous behavior did not match the documented intent of the settings involved.

  • Origin connect retries now honor HostDB state

    Traffic Server has three settings that bound how many times a failed origin connection is retried. Prior to this release none of them were applied according to the actual state of the origin, so the configured limits did not take effect as documented. The retry limit is now selected by the HostDBInfo state of the server being contacted:

    This is an intentional incompatibility. Deployments that relied on the previous behavior will see a different number of origin connect attempts after upgrading, most visibly toward origins HostDB considers DOWN, which are no longer retried at all. Review these three settings before upgrading.

Changes to Features

  • proxy.config.http.cache.ignore_accept_encoding_mismatch now honors Vary: Accept-Encoding at its documented default of 2. Previously any non-zero value was treated as “ignore the mismatch”, so the default did not behave as documented. Deployments that depended on the old behavior should set the value to 1 explicitly.

  • Replaced configurations are now destroyed on an ET_TASK thread instead of a network thread. This is transparent, but it moves config teardown work off the event loop.

Removed Features

  • The -k / --clear_hostdb command line flag and the PROXY_CLEAR_HOSTDB environment variable have been removed from traffic_server. The clear_hostdb command is still available via traffic_server -C clear_hostdb.

  • OpenSSL ENGINE support has been removed. It was unintentionally disabled in v10.0 and the API is gone in recent OpenSSL releases. The proxy.config.ssl.engine.conf_file record still exists but has no effect.

Configuration Changes

The following records.yaml changes have been made in v10.2:

See What’s New in ATS v10.2 for the full list of settings added in this release.

JSONRPC now refuses writes to records marked RECA_READ_ONLY or RECA_NO_ACCESS. Tooling that previously attempted such writes will now receive an error rather than silently having no effect.

Plugins

  • redo_cache_lookup has been moved out of the experimental plugins and into the examples. It is no longer built or installed.

  • header_rewrite now rejects an invalid run-plugin directive at configuration load time rather than at runtime. A configuration that was previously accepted and failed later will now fail to load.

ts::Metrics, in the installed tsutil/Metrics.h, no longer has an iterator. Metrics::iterator, begin(), end() and find() are removed, and enumeration is now Metrics::for_each(func), which invokes func(name, type, value) for each metric:

ts::Metrics::instance().for_each([](std::string_view name, ts::Metrics::MetricType type, int64_t value) {
  // ...
});

Handing out a position let a caller name a slot the store was free to change underneath them, which is what the iterator could not be made safe against. Reaching a single metric by name is lookup().

Metrics::Storage::createSpan() and Metrics::rename() are also removed. Spans handed out unnamed slots that only rename() could name, and rename() mutated a name that the lock free readers hand out views of.

Build

The Python tooling used by the test suite has migrated from Pipenv to uv. Developers running autests will need uv available; this does not affect runtime deployments.

Upgrading to ATS v10.x

Feature Changes

Removed and Deprecated Features

The following features, configurations and plugins are either removed or deprecated in this version of ATS. Deprecated features should be avoided, with the expectation that they will be removed in the next major release of ATS.

  • Removed Features * HostDB no longer supports persistent storage for DNS resolution * Removed support for the MMH crypto hash function * Removed the built-in stats and cache inspector pages that were previously accessible via the Traffic Server HTTP interface

    • Traffic Manager is no longer part of Traffic Server. Administrative tools now interact with Traffic Server directly by using the JSONRPC Endpoint.

      • traffic_ctl server

        As a part of the above feature removal the backtrace, restart, start, status options are no longer available in this Traffic Server version.

  • Deprecated Features

    • Next Protocol Negotiation (NPN) support has been deprecated from ATS and will be removed in the next major release.

  • Removed Libraries

    • mgmt_c - Client library for traffic_manager

Changes to Features

The following features have been changed in this version of ATS.

  • Remap ACLs

    Changed in-line ACLs to match before activated ACL rules. For details refer to: https://github.com/apache/trafficserver/pull/11033 and ACL Filters.

  • Administrative API (RPC)

    Moved away from the binary serialization mechanism used to comunicate between Traffic Server and the tools to a JSON-RPC text based protocol. Underlying Unix Domain Socket protocol remains the same. Check JSONRPC 2.0 Protocol for more details.

  • Other changes

    • It is now a fatal error when ATS cannot bind or listen to a configured port

    • Propagate socket options specified in proxy.config.net.sock_option_flag_in to newly accepted connections

    • HostDB internals were restructured, this should (externally) be backwards compatible. In any case you can check HostDB for more details.

API Changes

The following APIs have changed, either in semantics, interfaces, or both.

  • Changed TS API

    • TSHttpTxnAborted

    • TSMimeHdrPrint

    • Enum values for hooks and events have been changed (ABI incompatible change)

    • TSSslSecretGet

  • New TS API

    • TSContScheduleOnEntirePool

    • TSContScheduleEveryOnEntirePool

  • Removed TS API

    • TSContSchedule

    • TSHttpSsnArgSet

    • TSHttpSsnArgGet

    • TSHttpSsnArgIndexReserve

    • TSHttpSsnArgIndexNameLookup

    • TSHttpSsnArgIndexLookup

    • TSHttpTxnArgSet

    • TSHttpTxnArgGet

    • TSHttpTxnArgIndexReserve

    • TSHttpTxnArgIndexNameLookup

    • TSHttpTxnArgIndexLookup

    • TSHttpTxnClientPacketTosSet

    • TSHttpTxnServerPacketTosSet

    • TSMgmtConfigIntSet

    • TSUrlHttpParamsGet

    • TSUrlHttpParamsSet

    • TSVConnArgSet

    • TSVConnArgGet

    • TSVConnArgIndexReserve

    • TSVConnArgIndexNameLookup

    • TSVConnArgIndexLookup

    • TSRecordType::TS_RECORDTYPE_CLUSTER

    • TSRecordType::TS_RECORDTYPE_LOCAL

  • Removed INK UDP API

    • INKUDPBind

    • INKUDPSendTo

    • INKUDPRecvFrom

    • INKUDPConnFdGet

    • INKUDPPacketCreate

    • INKUDPPacketBufferBlockGet

    • INKUDPPacketFromAddressGet

    • INKUDPPacketFromPortGet

    • INKUDPPacketConnGet

    • INKUDPPacketDestroy

    • INKUDPPacketGet

Cache

The cache in this releases of ATS is compatible with previous versions of ATS. You would not expect to lose your cache, or have to reinitialize the cache when upgrading.

Configuration Changes

The following incompatible changes to the configurations have been made in this version of ATS.

The records.config file has been renamed to records.yaml and now it is structured in YAML format. Check Converting records.config to records.yaml and records.yaml for more details.

The following records.yaml changes have been made:

The following changes have been made to the sni.yaml file:

  • disable_h2 has been removed. Use http2 with off instead.

  • The ip_allow key can now take a reference to a file containing the ip allow rules

  • valid_tls_versions_in has been deprecated. Use valid_tls_version_min_in and valid_tls_version_max_in instead.

  • Simplify wildcard support and matching order of the fqdn field

    • Allow single left-most *

    • Do NOT support regex

    • Allow $1 (capturing) support in the tunnel_route field

    • Matching depends on the order of entries (like remap.config)

Plugins

Deprecated Plugins

The following plugins have been deprecated.

  • healthchecks - please use the statichit plugin instead

  • icap

Removed Plugins

The following plugins have been removed from the ATS source code in this version of ATS:

  • mysql_remap - Dynamic remapping of URLs using data from a MySQL database.

  • acme

  • cache_key_genid

  • fast_cgi

Changes to Features

The following plugins have been changed in this version of ATS.

  • regex_remap - matrix-parameters parameter has been removed. The string that follows a semicolon is now included in path.

  • header_rewrite - MATRIX part specifier has been removed. The string that follows a semicolon is now included in PATH part.

  • maxmind_acl - The regex part in its configuration takes the entire URL of a request, not just the path.

  • rate_limit - Few changes were made on this plugin:

    • A YAML based configuration, reloadable even as global plugin.

    • SNI aliases

    • The IP reputation objects are now shareable for many SNIs.

    for more details, please check Rate Limit Plugin.

Lua Plugin

  • The following Http config constants have been renamed:

TS_LUA_CONFIG_HTTP_CONNECT_ATTEMPTS_MAX_RETRIES_DEAD_SERVER has been renamed to TS_LUA_CONFIG_HTTP_CONNECT_ATTEMPTS_MAX_RETRIES_DOWN_SERVER.

TS_LUA_CONFIG_HTTP_CONNECT_DEAD_POLICY has been renamed to TS_LUA_CONFIG_HTTP_CONNECT_DOWN_POLICY.

  • The following functions have been removed:

    • ts.http.client_packet_tos_set

    • ts.http.server_packet_tos_set

    • ts.client_request.get_uri_params

    • ts.client_request.set_uri_params

    • ts.server_request.get_uri_params

    • ts.server_request.set_uri_params

Metrics

  • The HTTP connection metric proxy.process.http.dead_server.no_requests has been renamed to proxy.process.http.down_server.no_requests.

  • The network metric proxy.process.net.calls_to_readfromnet_afterpoll has been removed

  • The network metric proxy.process.net.calls_to_writetonet_afterpoll has been removed

  • New cache metrics proxy.process.cache.stripes and proxy.process.cache.volume_X.stripes that counts cache stripes

  • All metric names that ended in _stat have had that suffix dropped and no longer end with _stat

  • The metric proxy.node.cache.contents.num_doc was removed

  • The metric proxy.node.config.reconfigure_required was renamed to proxy.process.proxy.reconfigure_required

  • The metric proxy.node.config.reconfigure_time was renamed to proxy.process.proxy.reconfigure_time

  • The metric proxy.node.config.restart_required.proxy was renamed to proxy.process.proxy.restart_required

  • The metric proxy.node.restarts.proxy.cache_ready_time was renamed to proxy.process.proxy.cache_ready_time

  • The metric proxy.node.restarts.proxy.stop_time was renamed to proxy.process.proxy.start_time

  • The following traffic_manager metrics have been removed: - proxy.node.hostname_FQ - proxy.node.hostname - proxy.node.proxy_running - proxy.node.restarts.proxy.restart_count - proxy.node.restarts.proxy.start_time - proxy.node.http.parent_proxy_total_response_bytes

Logging

The cqtx log field has been removed, but can be replaced by cqhm pqu cqpv.

The cqhv log field has been removed.

The cpu, cquc, cqup, and cqus log fields have new names, pqu, pquc, pqup, and pqus. The old names have been deprecated.

The chi log field now represents the IP address of the previous hop if Proxy Protocol is used.