← Recipes

阅读中文版本

Diagnose HTTP 499 Client Aborts in nginx Logs

Find 499 entries in nginx access logs, correlate them with upstream response times, and decide whether clients time out too early or the server is too slow.

~25 minapinginxobservability

Task

Quantify 499 client aborts from nginx logs and determine whether the root cause is client timeout configuration or upstream latency.

When to use this

Monitoring shows zero 5xx errors, yet users complain the app feels broken. The evidence lives only in 499 log entries nobody alerts on.

Prerequisites

  • nginx in front of the application with the default combined or JSON log format
  • Access to the log files or log shipping
  • Knowledge of the client timeout settings

Steps

1. Count 499 responses grouped by endpoint and hour.

awk '$9 == 499 {print substr($4,2,14), $7}' /var/log/nginx/access.log | sort | uniq -c | sort -rn | head -20

Expected output: A table of timestamp and URI with counts shows exactly which endpoint loses clients and when the spike started.

2. Correlate aborts with upstream service time.

awk '$9 == 499 {print $upstream_response_time}' /var/log/nginx/access.log 2>/dev/null || grep ' 499 ' /var/log/nginx/access.log | head -5

Expected output: Upstream times clustering just above a round number like 10.000 point to a client-side timeout slightly shorter than real response time.

3. Compare against completed requests for the same endpoint.

awk '$7 == "/api/report" && $9 == 200 {n++; t+=$upstream_response_time} END {if (n) print "avg_upstream", t/n, "n", n}' /var/log/nginx/access.log

Expected output: The same endpoint succeeding with a 12-second average confirms the server is slow, not the client impatient.

4. Instrument the slow path and fix the dominant span.

curl -s -o /dev/null -w "ttfb=%{time_starttransfer}\n" http://origin.internal/api/report

Expected output: A direct origin measurement close to the logged upstream time rules nginx out and hands the latency to the application team.

Troubleshooting

Problem

No 499 entries at all

Solution

The log format omits status or logs at a level that filters them; switch to a JSON log format including upstream_response_time and request_time.

Problem

499 spikes but upstream is fast

Solution

Clients or an intermediate proxy abort on their own timers; check SDK defaults and proxy read timeouts on the calling side before optimizing the server.

Problem

Cannot read upstream_response_time

Solution

The variable is empty when no upstream was contacted, for example on malformed requests; guard the awk field with a length check.

Limitations

  • 499 records that the client aborted, not why; the reason needs client-side logs or a correlation id.
  • Aggressive client retries can hide 499 by re-succeeding, so also watch duplicate-request rates.

The error code only nginx can see

When a user gives up and closes the connection, nginx logs status 499 and the application never finishes the request, so your app metrics stay green while the experience degrades. Mining the access log for 499 and joining it with upstream_response_time tells you which story is true: clients walking away from genuinely slow responses, or clients aborting on timeouts shorter than the work requires.

# 499 per endpoint and hour
awk '$9 == 499 {print substr($4,2,14), $7}' /var/log/nginx/access.log \
  | sort | uniq -c | sort -rn | head -20

Round numbers are confessions

Upstream times that cluster at 9.9 or 10.0 seconds mean something timed out at exactly ten seconds, and that something is usually on the client side. When the same endpoint completes successfully with a twelve-second average, the honest fix is either making the endpoint fast or moving it to an asynchronous job, not raising the client timeout and hoping.

Alert on 499, not only 5xx

A dashboard that only counts 5xx will show a perfectly healthy service while every mobile user on a slow network abandons it. Add a 499 rate per endpoint to alerting with a threshold tuned per route, since long-running report exports legitimately tolerate more aborts than interactive searches.