GUI opened a new issue, #13549: URL: https://github.com/apache/trafficserver/issues/13549
## Summary When Traffic Server is proxying a request to an upstream server and the client aborts the request before the upstream server has responded at all, Traffic Server appears to still try and complete the request, rather than cancelling the request and relaying this cancellation to the upstream server. Under Traffic Server 9.2 and 10.0, this behavior can seemingly be controlled by [`proxy.config.http.allow_half_open`](https://docs.trafficserver.apache.org/en/latest/admin-guide/files/records.yaml.en.html#proxy-config-http-allow-half-open), but in Traffic Server 10.1.4 and 10.2.0-rc1, I can't find any way to have Traffic Server abort these canceled client requests. In situations where the upstream server is very slow to respond and clients cancel many requests, Traffic Server still holds open the connections for any cancelled requests to the upstream server. In a worst-case scenario, this may eventually cause Traffic Server to hit its own `proxy.config.net.max_requests_in` or `proxy.config.net.connections_throttle` limits if it's completely occupied trying to fulfill all of the canceled requests. I realize there are some situations where you'd maybe want to try and let the upstream requests complete, but I'm trying to figure out why changing that `allow_half_open` setting doesn't seem to affect 10.1 and 10.2 in the same way as before. Based on the docs, I was also wondering if [`proxy.config.http.background_fill_active_timeout`](https://docs.trafficserver.apache.org/en/latest/admin-guide/files/records.yaml.en.html#proxy-config-http-background-fill-active-timeout) or [`proxy.config.http.background_fill_completed_threshold`](https://docs.trafficserver.apache.org/en/latest/admin-guide/files/records.yaml.en.html#proxy-config-http-background-fill-completed-threshold) could play a role, but regardless of settings, I can't get these requests canceled by the client to stop processing in Traffic Server 10.1 or 10.2. So, am I missing some other setting to control this, or is this a bug in 10.1 and 10.2? ## Possibly related PRs I'm proxying over HTTP 1.1, if that's relevant. I dug up several semi-recent PRs that seem to be touching this code, but they all seem maybe more related to HTTP 2 behavior, so I'm wondering if maybe this is no longer working properly for HTTP 1.1 proxied requests (but I haven't verified things with anything besides HTTP 1.1): - https://github.com/apache/trafficserver/pull/12529 - https://github.com/apache/trafficserver/pull/13523 - https://github.com/apache/trafficserver/pull/12999 ## Logs and related code Debug logging indicates that when the client cancels the request, Traffic Server is hitting the `state_watch_for_client_abort` handler with a `VC_EVENT_EOS` event: ``` [ET_NET 0] DIAG: <HttpSM.cc:2795 (main_handler)> (http) [2] VC_EVENT_EOS/TS_EVENT_VCONN_EOS, 104 [ET_NET 0] DIAG: <HttpSM.cc:896 (state_watch_for_client_abort)> (http) [2] [state_watch_for_client_abort, VC_EVENT_EOS/TS_EVENT_VCONN_EOS] ``` With `allow_half_open` disabled, then in 10.1.4 or 10.2.0-rc1, it's landing in this `else if` block: https://github.com/apache/trafficserver/blob/b1df7334b39a878971c376da849e8da4984918b6/src/proxy/http/HttpSM.cc#L924-L927 However, if I remove that `else if` block entirely (so it falls into the `else` logic), then the request is canceled as I was originally expecting. It seems like that `else if` block was intentionally added by https://github.com/apache/trafficserver/pull/12529 to fix a very similar sounding issue, though. I'm not familiar enough with the codebase or what that PR was originally fixing to know what the proper solution is here, but it seems like some of these more recent changes to `state_watch_for_client_abort` could be playing a role. ## Reproduction Here's a little repo (`client-abort` branch) showing how the cancellation behavior doesn't seem to be working as I'd expect in Traffic Server 10.1 and 10.2: https://github.com/GUI/trafficserver-debugging/tree/client-aborts This reproduction essentially consists of an nginx upstream server that sleeps for 10 seconds and then responds. Traffic Server is proxying to this upstream with the `allow_half_open` option disabled. With Traffic Server 9.2, 10.0, or nginx itself proxying, you can see the upstream connection is aborted after the client cancels the request. However, in Traffic Server 10.1.4 or 10.2.0-rc1, the upstream connection continues until it is complete (which is not what I want with `allow_half_open` disabled). ### Direct upstream request with timeout ```sh curl -w 'time_total: %{time_total}s\n' --max-time 2 'http://localhost:8081/' # curl: (28) Operation timed out after 2005 milliseconds with 0 bytes received # time_total: 2.004165s ``` Server logs show nginx upstream canceling request immediately after client hangs up (after 2 seconds): ``` nginx-1 | 192.168.65.1 - - [14/Aug/2026:04:07:06 +0000] "GET / HTTP/1.1" 499 0 "-" "curl/8.7.1" request_time=2.004 msec=1786680426.901 ``` ### Traffic Server 9.2/10.0 cancellation ```sh curl -w 'time_total: %{time_total}s\n' --max-time 2 'http://localhost:10100/' # curl: (28) Operation timed out after 2006 milliseconds with 0 bytes received # time_total: 2.006394s ``` Server logs show both nginx upstream and Traffic Server closing connection after the 2 second client timeout. ``` nginx-1 | 192.168.224.2 - - [14/Aug/2026:04:08:50 +0000] "GET / HTTP/1.1" 499 0 "-" "curl/8.7.1" request_time=1.998 msec=1786680530.387 ts-10-0-1 | 192.168.65.1 - - [14/Aug/2026:04:08:48 -0000] "GET http://nginx:8081/ http/1.1" 000 0 000 0 0 0 90 0 226 17 2 EMPTY INTR FIN ERR_CLIENT_ABORT ttms=2009 stms=-1 ``` ### BUG SCENARIO: Traffic Server 10.1.4/10.2.0-rc1 not aborting ```sh curl -w 'time_total: %{time_total}s\n' --max-time 2 'http://localhost:10102/' # curl: (28) Operation timed out after 2002 milliseconds with 0 bytes received # time_total: 2.002365s ``` Despite the client hanging up after 2 seconds, server logs show that both Traffic Server and the nginx upstream kept the connection open for the full 10 seconds it took for the upstream to respond (see `request_time` and `ttms` in log output): ``` nginx-1 | 192.168.224.4 - - [14/Aug/2026:04:11:18 +0000] "GET / HTTP/1.1" 200 29 "-" "curl/8.7.1" request_time=10.001 msec=1786680678.975 ts-10-2-1 | 192.168.65.1 - - [14/Aug/2026:04:11:08 -0000] "GET http://nginx:8081/ http/1.1" 200 0 200 0 0 0 90 177 226 148 10 DIRECT INTR FIN ERR_CLIENT_READ_ERROR ttms=10020 stms=10007 ``` ### nginx proxy cancellation Just for comparison, there's also an nginx proxy in front of the nginx upstream: ```sh curl -w 'time_total: %{time_total}s\n' --max-time 2 'http://localhost:10092/' curl: (28) Operation timed out after 2003 milliseconds with 0 bytes received time_total: 2.003557s ``` You can see this nginx proxy behaves the same as Traffic Server 9.2 or 10.0, with both requests being canceled after the 2 second client timeout: ``` nginx-1 | 192.168.65.1 - - [14/Aug/2026:04:13:02 +0000] "GET / HTTP/1.1" 499 0 "-" "curl/8.7.1" request_time=2.007 msec=1786680782.467 nginx-1 | 127.0.0.1 - - [14/Aug/2026:04:13:02 +0000] "GET / HTTP/1.1" 499 0 "-" "curl/8.7.1" request_time=2.005 msec=1786680782.467 ``` -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. To unsubscribe, e-mail: [email protected] For queries about this service, please contact Infrastructure at: [email protected]
