<!-- 499 Client Closed Request: what it means — Uptimely -->
> Markdown version of https://getuptimely.com/errors/499 — the page itself is the canonical copy.

Error guide

# 499 Client Closed Request

Nginx's own code for a client that hung up before the response was ready — a symptom of slowness, not a cause.

499 is not part of the HTTP specification. It is a code nginx writes into its own access log when a client disconnects before the response was sent — no response ever went out, so nothing received a 499\. It exists purely so the log can record what happened.

That makes it a symptom with an unusually clear meaning. A client gave up waiting, which means the response was slow enough that something decided it was not coming: a user navigating away, a mobile app hitting its own timeout, a load balancer or a client library cutting the connection at a deadline shorter than the server's.

So the interesting number is never the 499s themselves — it is what the upstream was doing at the time. A rise in 499s is one of the earliest signals of a saturating backend, and it appears before the 502s and 504s that follow, because clients start giving up before the server does.

## Common causes

- Upstream responses slow enough that clients time out first.
- A client-side or load-balancer timeout shorter than the server's own.
- Users abandoning a slow page or an app cancelling an in-flight request.
- A saturated connection pool or thread pool making requests queue before any work starts.
- Long-polling or streaming connections closing normally, which produce 499s that mean nothing.

## How to diagnose it

1. Correlate 499s against upstream response time — they almost always track the tail latency.
2. Compare each layer's timeout: the shortest one decides who gives up first, and it is often the client.
3. Separate long-polling and streaming endpoints, whose normal closes are indistinguishable in the log.
4. Look for a matching rise in 502 or 504 shortly afterwards, which confirms the upstream is degrading.
5. Check queue depth and pool saturation on the upstream at the times of the spikes.

## Whose fault is it? The server's side

Formally the client closed the connection, but in practice a rise in 499s is a server-side latency problem. The client only gave up because the answer was late.

## What monitoring sees

An external monitor will never receive a 499 — it is a log-only code — so it will not appear in check history at all. What a monitor can see is the cause: rising response time before failures start. A response-time threshold on a monitor catches this phase, which is the whole argument for alerting on latency rather than only on availability.

## Related error guides

- [504 Gateway Timeout](https://getuptimely.com/errors/504)
- [502 Bad Gateway](https://getuptimely.com/errors/502)
- [408 Request Timeout](https://getuptimely.com/errors/408)
- [5xx server errors](https://getuptimely.com/errors/5xx)

## Terms used on this page

- [Response time](https://getuptimely.com/glossary/response-time)
- [Degraded performance](https://getuptimely.com/glossary/degraded-performance)
- [Mean time to detect (MTTD)](https://getuptimely.com/glossary/mttd)

## Questions

### Is 499 a real HTTP status code?

No. It is nginx's own log-only code for a client that disconnected before the response was sent. Nothing ever receives a 499, which is why your monitoring will never report one.

### How do I stop 499 errors?

Make the upstream faster, or reconcile the timeouts so the server is not still working on a request every client has already abandoned. Suppressing the log line changes nothing about what is happening.

One of the [Uptimely HTTP and network error guides](https://getuptimely.com/errors), written for the person who operates the server rather than the one refreshing the page. Something here read wrong to you? Email **support@getuptimely.com**.
