Upgrading to ATS v11.x
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.
API Changes
The handle returned by TSPortDescriptorParse() must now be released
with TSPortDescriptorDestroy(). The descriptor can be destroyed
immediately after TSPortDescriptorAccept() returns because the
listener does not retain it.
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.
traffic_ctl Changes
traffic_ctl grades a server error by the severity of its annotations, see
traffic_ctl --error-level. An annotation without a severity counts as an error, so with
the default level, error, the exit status only changes in these cases:
traffic_ctl server drainon a server that is already draining, andtraffic_ctl server drain --undoon one that is not, report a warning and exit0. They used to exit2. Pass--error-level=warnto keep treating them as failures.With
--format json, a server error sets the exit status, as in text output. Most commands used to exit0in that case.traffic_ctl server debug enable --appendsets nothing when the request that reads the current tags fails, and exits2, or75when the error is below the level. It used to set the new tags on their own, replacing the current ones.
Annotations that carry a severity are printed with it, for example - [3000] Warn: Server already
draining., and a JSONRPC error data entry carries a severity field when its handler sets
one, see Severity.
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.yamlnow ships outbound rules that denyCONNECTtunnels to unspecified, loopback, private, link-local and IPv4-mapped IPv6 destination addresses. If a deployment intentionally proxiesCONNECTto one of those ranges, add a more specificapply: outallow rule before the deny rule: the first matching range determines the outcome.proxy.config.http2.default_buffer_water_marknow defaults to32768instead of-1, and its accepted range is now1024to4294967295. A configuration that explicitly set this to-1, or to any value below1024, is no longer valid and must be updated or removed.The
tsmemcacheplugin 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_sizeaccepts0to65535, andproxy.config.hostdb.round_robin_max_countaccepts1to1024.
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
HEADrequest carryingContent-LengthorTransfer-Encodingis rejected. Setproxy.config.http.reject_head_with_contentto0to restore the previous behavior.A
Transfer-Encodingwhose final coding is notchunkedis rejected, as is anyTransfer-Encodingappearing in HTTP/2 or HTTP/3 request headers, where the field has no meaning.Chunked parsing is stricter in two further ways: a bare
LFterminating a chunked trailer is rejected under strict parsing, and a chunk extension quoted-string value containingCRorLFis rejected.A header field longer than the 16-bit field-length limit is rejected rather than silently truncated to its low 16 bits. A
Hostheader 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
302carrying aLocationheader 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
CONNECTnow applies only to successful responses, so an error response to aCONNECTis 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.
CONTINUATIONaccumulation that would overflow the header block length is rejected. Outstanding HTTP/2SETTINGSframes are bounded, and an unnecessarySETTINGSframe closes the connection.HTTP/2
Content-Lengthis 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.@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 (CVE-2026-33267).Headers named in the
Connectionfield 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.
The Proxy Protocol allowlist is consulted only once the header preface has been seen, so an allowlisted peer that sends no PROXY header is treated as though it sent none rather than inheriting the allowlisted path.
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_IpAllowapplies 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_clientpolicy 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 matchingsni.yamlentry 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 anExpect: 100-continuePOSTis no longer forwarded as a new request (CVE-2025-55702).The outbound
server_nameSNI 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.configretries are capped at one per window, so a parent that is failing cannot be retried repeatedly within the same window.
Plugins
origin_server_authstrips client-suppliedx-amz-request headers that fall outside the scope its signature covers, rather than forwarding headers the signature does not authenticate.magickrequires a signing key and allowlists theconvertoperators it will run. An existing configuration without a signing key will not load.esibounds nested ESI comments and request length, and validatesesi:includeURLs before fetching them.certifierrejects 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_transformbounds both the buffered body and the ImageMagick decode,stale_responsecaps its buffering,xdebugcaps theX-Remapheader to the buffer content,multiplexerrejects oversized chunks, andurl_sigrequires the delimiter in itsC=parameter.combo_handlerrejects an emptyContent-Typewhen an allowlist is configured;compressstops the transform after adeflate()error rather than continuing;prefetchconstrains relative paths;rate_limitno 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_rulesand 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_mapinremap.configandfqdninsni.yamlalready require a whole-subject match and are unaffected by the setting (CVE-2026-22068).
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
serverAs a part of the above feature removal the
backtrace,restart,start,statusoptions 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_into newly accepted connectionsHostDB 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 records.yaml entry
proxy.config.http.down_server.abort_thresholdhas been removed.The records.yaml entry
proxy.config.http.connect_attempts_max_retries_dead_serverhas been renamed toproxy.config.http.connect_attempts_max_retries_down_server.The records.yaml entry
proxy.config.http.connect_attempts_max_retries_down_serveris now deprecated in favor ofproxy.config.http.connect_attempts_max_retries_suspect_server. The new name aligns with theHostDBInfo::State::SUSPECTstate it actually applies to (a recovering origin allowed a limited probe budget afterproxy.config.http.down_server.cache_timeelapses). When only the deprecated record is set, its value is mirrored forward to the new record and a warning is logged. When both are set, the new record wins.The entry
proxy.config.http.connect.dead.policyhas been renamed toproxy.config.http.connect.down.policy.The records.yaml entry
proxy.config.http.parent_proxy.connect_attempts_timeoutandproxy.config.http.post_connect_attempts_timeouthave been removed. Instead useproxy.config.http.connect_attempts_timeoutto control all connection to origin timeouts.The per server origin connection feature had a few configurations that were not used removed.
proxy.config.http.per_server.connection.queue_sizeandproxy.config.http.per_server.connection.queue_delayhave been removed.The default value for records.yaml entry
proxy.config.ssl.client.verify.server.policyhas been changed fromPERMISSIVEtoSTRICT.All
proxy.config.ssl.TLSv*andproxy.config.ssl.client.TLSv*have been deprecated. Useproxy.config.ssl.server.version.min/maxandproxy.config.ssl.client.version.min/maxinstead.The records.yaml entry
proxy.config.http.keepalive_internal_vchas been removed. This entry was previously undocumented.The default values for
proxy.config.http.request_header_max_size,proxy.config.http.response_header_max_size, andproxy.config.http.header_field_max_sizehave been changed to 32KB.The records.yaml entry
proxy.config.http.server_portsnow also accepts theallow-plainoptionThe records.yaml entry
proxy.config.http.proxy_protocol_allowlistis now enforced only for connections on Proxy Protocol-enabled ports that begin with a Proxy Protocol header preface. Non-Proxy Protocol traffic on flexible Proxy Protocol ports is no longer restricted by this setting; useip_allow.yamlfor general source-IP access control.The records.yaml entry
proxy.config.http.cache.max_open_write_retry_timeouthas been added to specify a timeout for starting a write to cacheThe records.yaml entry
proxy.config.net.per_client.max_connections_inhas been added to limit the number of connections from a client IP. This works the same asproxy.config.http.per_server.connection.maxThe records.yaml entry
proxy.config.http.no_dns_just_forward_to_parentis not overridableThe records.yaml entry
proxy.config.output.logfilehas been renamed toproxy.config.output.logfile.name.The records.yaml entry
proxy.config.exec_thread.autoconfighas been renamed toproxy.config.exec_thread.autoconfig.enabled.The records.yaml entry
proxy.config.tunnel.prewarmhas been renamed toproxy.config.tunnel.prewarm.enabled.The records.yaml entry
proxy.config.ssl.origin_session_cachehas been renamed toproxy.config.ssl.origin_session_cache.enabled.The records.yaml entry
proxy.config.ssl.TLSv1_3has been renamed toproxy.config.ssl.TLSv1_3.enabled.The records.yaml entry
proxy.config.ssl.client.TLSv1_3has been renamed toproxy.config.ssl.client.TLSv1_3.enabled.The records.yaml entry
proxy.config.allocator.iobuf_chunk_sizeshas been added to enable more control of iobuffer allocation.The records.yaml entry
proxy.config.allocator.hugepageswill enable allocating iobuffers and cache volumes from hugepages if configured in the system.The records.yaml entry
proxy.config.plugin.compiler_pathhas been added to specify an optional compiler tool path for compiling plugins.The default value of
proxy.config.http.server_session_sharing.matchis unchanged atboth, butbothnow selectscertin addition toipandhost. A pooled outbound TLS session is only reused for a transaction that would present the same client certificate, because the origin authorizes the connection on the certificate sent during the handshake and reuse performs no second handshake. Deployments that overrideproxy.config.ssl.client.cert.filenameper remap rule or from a plugin will see outbound sessions pool per certificate, and so more outbound handshakes. Setip,hostexplicitly to select whatbothselected before.
The ssl_multicert.config file has been replaced with
ssl_multicert.yaml. The new file uses YAML format with a top-level
ssl_multicert key containing a sequence of certificate entries. Use
traffic_ctl config convert ssl_multicert to convert existing
configuration files:
traffic_ctl config convert ssl_multicert ssl_multicert.config ssl_multicert.yaml
See ssl_multicert.yaml for the new format documentation.
The following changes have been made to the sni.yaml file:
disable_h2has been removed. Usehttp2withoffinstead.The
ip_allowkey can now take a reference to a file containing the ip allow rulesvalid_tls_versions_inhas been deprecated. Usevalid_tls_version_min_inandvalid_tls_version_max_ininstead.Simplify wildcard support and matching order of the
fqdnfieldAllow single left-most
*Do NOT support regex
Allow
$1(capturing) support in thetunnel_routefieldMatching 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
YAMLbased 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_afterpollhas been removedThe network metric
proxy.process.net.calls_to_writetonet_afterpollhas been removedNew cache metrics
proxy.process.cache.stripesandproxy.process.cache.volume_X.stripesthat counts cache stripesThe cache metrics
proxy.process.cache.direntries.usedandproxy.process.cache.volume_X.direntries.usednow keep counting stale directory entries until they are reclaimed, at the latest by the next cache cycle wrap, so they read higher through each cycle and drop at the wrapAll metric names that ended in
_stathave had that suffix dropped and no longer end with_statThe metric
proxy.node.cache.contents.num_docwas removedThe metric
proxy.node.config.reconfigure_requiredwas renamed toproxy.process.proxy.reconfigure_requiredThe metric
proxy.node.config.reconfigure_timewas renamed toproxy.process.proxy.reconfigure_timeThe metric
proxy.node.config.restart_required.proxywas renamed toproxy.process.proxy.restart_requiredThe metric
proxy.node.restarts.proxy.cache_ready_timewas renamed toproxy.process.proxy.cache_ready_timeThe metric
proxy.node.restarts.proxy.stop_timewas renamed toproxy.process.proxy.start_timeThe 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.