From be69c090d93973f48aae8d43030bccc3aaed0760 Mon Sep 17 00:00:00 2001
From: Nic <123965403+ngayerie@users.noreply.github.com>
Date: Fri, 23 Oct 2026 10:32:47 +0200
Subject: [PATCH] [Support] Improve HTTP 499 troubleshooting guide
Expand the 499 troubleshooting page based on Q3 2026 support case analysis.
Addresses all review comments from dpolaske-cloudflare.
connection-limits.mdx changes are split into PR #34522.
---
.../4xx-client-error/error-499.mdx | 101 ++++++++++++++----
1 file changed, 82 insertions(+), 19 deletions(-)
diff --git a/src/content/docs/support/troubleshooting/http-status-codes/4xx-client-error/error-499.mdx b/src/content/docs/support/troubleshooting/http-status-codes/4xx-client-error/error-499.mdx
index f37ff257b10..421913c975e 100644
--- a/src/content/docs/support/troubleshooting/http-status-codes/4xx-client-error/error-499.mdx
+++ b/src/content/docs/support/troubleshooting/http-status-codes/4xx-client-error/error-499.mdx
@@ -7,36 +7,99 @@ products:
- support
---
+import { Steps } from "~/components";
+
## 499 Client Close Request
-The `HTTP 499` response code typically occurs when a client terminates the connection before the server is able to respond.
+Cloudflare records a 499 status code in logs and analytics when a client closes the connection before the request is complete. No 499 HTTP response is sent to the client — the code only appears in logs.
-### Common use cases
+Clients disconnect for ordinary reasons — page navigation, app cancellation, or a request deadline — and a low 499 rate on any zone is expected and does not indicate a fault. Investigate when the rate rises noticeably above your zone's normal baseline, persists at a specific Cloudflare data center, or affects a latency-sensitive endpoint.
-Examples of `499` response code include situations where a client times out and closes the connection before the server completes processing, such as during large file uploads or long-running requests. They can also occur due to issues in the TCP three-way handshake, where the client terminates the connection prematurely because of its timeout settings.
+### Common patterns to investigate
-### Cloudflare-specific information
+A 499 by itself does not identify a cause or locate a fault. A short client deadline combined with increased latency anywhere in the request path — origin connection, origin response, cache fill, edge processing, or response body delivery — can produce a higher 499 rate. Diagnosing which part of the path contributed requires comparing multiple log fields and matched request populations together.
-The `499 Client Closed Request` status code is specific to nginx and indicates that the client closed the connection while the server was still processing the request, preventing the server from sending a status code in response. This status code appears in [Cloudflare Logs](/logs/) and status code analytics for Enterprise customers.
+Common patterns that produce elevated 499 rates include:
-:::note
-Since Cloudflare is built on nginx, the 499 HTTP code is also logged in Cloudflare Logs and analytics for connections terminated by clients before Cloudflare has finished processing the request. It is expected to occasionally see these entries in your logs as clients close connections.
-:::
+| Pattern | Signals to look for | Starting point |
+|---|---|---|
+| **Client deadline shorter than path latency** | Rate elevated on specific endpoints. Matched completed requests on those endpoints show elevated `OriginResponseDurationMs` or longer edge times | Compare matched completed requests for the same endpoint and window. Check origin-side timing |
+| **Cache miss increasing latency** | Cache hit rate dropped for affected paths. The 499 rate tracks the hit-rate change | Check cache configuration for affected paths |
+| **Possible edge or network issue** | Rate notably elevated in one data center relative to matched cohorts elsewhere, with no explanation established from client timing, origin-side evidence, or cache behavior | Collect request-linked evidence and matched-cohort comparisons. Contact Cloudflare Support if unresolved |
+
+### How to investigate
+
+Use [Instant Logs](/logs/instant-logs/) or a [Logpush](/logs/logpush/) export to collect requests for the affected endpoint, client population, protocol, and time window. Keep both the `499` log entries and the other eligible requests. An export filtered only to `EdgeResponseStatus = 499` cannot provide comparison requests or the denominator needed to calculate a `499` rate.
+
+Calculate the `499` rate as requests with `EdgeResponseStatus = 499` divided by all eligible requests in the same population. If the logs are sampled, account for sampling consistently in both counts. For Instant Logs, use the returned `sampleInterval` values when estimating request counts. Use matched completed requests separately to compare timing fields.
+
+No single field identifies the cause. Correlate these fields with matched request populations and request-linked evidence:
+
+- **`OriginIP`** — the origin IP recorded for the request. An absent value does not establish where the request stopped. A request served from cache may not require an origin fetch. An aborted or incompletely logged request may also lack an origin IP. Correlate this field with `CacheCacheStatus` and request-linked evidence.
+- **`CacheCacheStatus`** — records cache disposition in the [HTTP requests dataset](/logs/logpush/logpush-job/datasets/zone/http_requests/). Values such as `hit` or `stale` indicate a cache-served response, where an absent origin IP may be expected. The `dynamic` value means the request is not eligible for cache and can include firewall-blocked requests. Values such as `miss` or `bypass` help identify requests to investigate. They do not establish that an origin connection was attempted or where an aborted request stopped. Collect request-linked and origin-side evidence before attributing a cause.
+- **`EdgeColoCode`** — if 499 errors are elevated at one data center, compare the 499 rate relative to eligible traffic for the same endpoint, client population, and protocol across data centers in the same window. A rate notably higher in one location than in matched cohorts elsewhere is a useful lead, but location alone does not identify an infrastructure fault.
+- **UTC time window and volume trend** — compare `499` rates for the same endpoint, client population, and protocol across time windows. Use all eligible requests in each matched population as the denominator. Differences in traffic mix can produce different `499` rates without identifying a fault.
+
+To investigate a 499 spike:
+
+
+
+1. Identify the affected endpoints and time windows. Calculate the `499` rate using all eligible requests for the same endpoint, client population, and protocol. Compare that rate with the normal baseline for the same population. Use matched completed requests for the separate timing comparison in the next step.
+2. Compare `OriginResponseDurationMs` on matched completed requests with the normal baseline for the same endpoint, client population, and protocol. The field measures upstream response time from the first Cloudflare data center that receives the request. It includes Argo Smart Routing and Tiered Cache time, plus time to connect to and receive a response from the origin. An elevated value does not identify where the delay occurred. Correlate it with origin-side timing and request-linked evidence. Do not use a timing value from a `499` entry alone to infer the failed phase or assign the delay to the origin server.
+3. Review `OriginIP` and `CacheCacheStatus` for the affected requests. Compare the `499` rate across data centers using matched endpoint, client, and protocol populations in the same window. An absent origin IP with `miss` or `bypass` is a lead to correlate with request-linked and origin-side evidence. If the elevated rate remains unexplained, contact Cloudflare Support with the affected window, sample Ray IDs, and matched-cohort comparisons.
+
+
+
+### TCP connection timing
+
+The [Connection limits reference](/fundamentals/reference/connection-limits/) publishes a 19-second TCP connection establishment limit for the origin-connect phase. A client that disconnects during origin connection establishment will produce a 499 log entry.
-To provide more context, a TCP connection must be established between Cloudflare and the website's origin server before any higher protocol (such as HTTP) begins communication. TCP uses a three-way handshake to establish connection:
+This is one phase in which a 499 can occur. Clients can also disconnect during the HTTP request phase, while response headers are being sent, or while the response body is being delivered. Identifying which phase was in progress when the client disconnected requires comparing `EdgeTimeToFirstByteMs`, `EdgeResponseBodyBytes`, and matched completed requests rather than inferring it from the 499 entry alone.
-- **SYN**: Cloudflare sends a SYN packet to the origin server.
-- **SYN+ACK**: The origin server responds with a SYN+ACK packet.
-- **ACK**: Cloudflare sends an ACK packet back to the origin server.
+### Long-running and streaming responses
+
+A 499 can occur before the first byte is delivered or after response-body delivery has begun, if the client disconnects before the response is complete. For example, a client with a short deadline may disconnect during origin connection or response. A client with a longer deadline may disconnect partway through receiving a large response body.
+
+For streaming responses (HLS, DASH, or other media formats) and other long-running requests, clients use varying connection and read timeout defaults, some configurable at the application level and some not.
+
+To investigate 499 errors for long-running or streaming responses:
+
+
+
+1. Confirm the effective timeout in use — check the client or SDK documentation and, if possible, confirm with your development team whether the timeout is configurable.
+2. Check `EdgeTimeToFirstByteMs` and `EdgeResponseBodyBytes` for the `499` log entries. Compare them with matched completed requests on the same paths. Positive response-body bytes support that body delivery had begun. Zero or missing body bytes do not, by themselves, establish that the disconnect occurred before the first byte. Use client-side timing or request-linked evidence when the phase remains unclear.
+3. If the affected paths are cacheable and their cache hit rate has dropped, check the cache configuration. A lower hit rate increases origin fetches and can raise latency for both first-byte and body delivery.
+4. Compare the `499` rate across data centers using matched paths, client populations, and protocols. Use all eligible requests in each population as the denominator. If one data center is significantly elevated with no origin-side or cache explanation, contact Cloudflare Support.
+
+
+
+### Transaction-sensitive requests
+
+When a `499` is logged for a request intended to modify server state, the log entry alone does not establish the operation's outcome. The client may have received response headers or part of the response body before disconnecting. If the application has not confirmed the result, reconcile the operation before retrying it.
+
+To handle an unconfirmed outcome:
+
+- Match the affected request and operation identifiers to your application's transaction records or operation-status endpoint. Follow the application's reconciliation and retry policy if the outcome remains pending or unknown.
+- Where your application supports idempotency keys, use them for state-changing endpoints. Reuse the same key when retrying the same operation, following the application's documented key scope, retention period, and retry behavior.
+
+:::note
+[RFC 9110](https://www.rfc-editor.org/rfc/rfc9110.html#section-9.2.2) defines `DELETE` as idempotent in its intended effect. Repeating the same request is defined to have the same intended effect as making it once. This does not establish the first request's outcome. Use application-level evidence to resolve an unconfirmed result.
+:::
-At this point, the connection is established, and both Cloudflare and the origin server can communicate. However, if the origin server does not send a SYN+ACK back to Cloudflare within 19 seconds, Cloudflare retries once more, with another 15-second timeout.
+### When to contact Cloudflare Support
-Depending on the client-side timeout settings, the following scenarios can occur:
+Contact support when:
-- **Shorter client timeout (less than 38 seconds)**: If the client has a shorter timeout, it will abandon the connection before Cloudflare completes processing, and a `499` response code will be logged.
-- **Successful connection (more than 38 seconds)**: If the client has a longer timeout and the TCP connection is successfully established, the HTTP transaction proceeds normally, and Cloudflare returns a standard status code (`HTTP 200`).
-- **Handshake failure**: If the client has a longer timeout but Cloudflare cannot establish the TCP handshake with the origin server, Cloudflare will return an `HTTP 522` status code.
+- 499 errors spike clearly above your zone's normal baseline for the same endpoints and window, and the spike is not explained by a corresponding change in origin response time or cache hit rate.
+- The affected requests have no recorded `OriginIP` and a `CacheCacheStatus` of `miss` or `bypass`, and the elevated `499` rate remains unexplained after reviewing matched request populations, client timing, and origin-side evidence. Include these field values as investigation clues, not as proof of a Cloudflare fault.
+- The 499 rate is significantly elevated in one data center relative to matched traffic in other data centers serving the same zone in the same window, with no origin-side or cache explanation.
-### Diagnose with Origin Analytics
+When you contact support, include:
-Use [Origin Analytics](/speed/origin-analytics/) to check whether slow origin response times are causing clients to close connections prematurely. If P95 origin response times are high, identify the slow endpoints in the **Top endpoints** table and optimize them to reduce `499` errors.
+- The affected hostname and zone ID
+- The UTC time window (start and end)
+- 10–20 Ray IDs from the 499 log entries
+- The `OriginIP` and `CacheCacheStatus` values for those log entries
+- The `EdgeColoCode` distribution for the 499 entries and the same-window 499 rate in matched cohorts at other data centers
+- Whether other zones or hostnames experienced the same spike simultaneously
+- For Enterprise customers: a [Logpush](/logs/logpush/) export containing the affected `499` entries and matched comparison requests for the time window