Nginx Custom Status Codes

Nginx non-standard status codes explained: 444 (connection drop), 494 (header too large), 495 (SSL error), 496 (no cert), 499 (client disconnect). Reading nginx logs.

Nginx Custom Status Codes: 444, 494, 495, 496, 499

Nginx defines several status codes not in the IANA registry. These codes appear in nginx access logs and error pages to describe connection-level events that the standard HTTP status code set cannot express precisely enough. Seeing a 499 in your nginx logs means a client closed the connection before nginx sent the response: useful for diagnosing timeout mismatches.1 A 444 means nginx deliberately dropped the connection without sending any response.2 A 494 means the request headers were too large for nginx's configured buffer.3 These codes are never sent to browsers as standard HTTP responses: browsers never see them as response status codes. Instead, they appear exclusively in nginx's own access and error logs. Understanding them prevents misdiagnosis of log anomalies that look alarming but have specific, diagnosable causes.

Nginx's non-standard codes

  • No Response — nginx drops the connection with no bytes sent
  • Request Header Or Cookie Too Large — exceeds large_client_header_buffers
  • SSL certificate error / required — mutual TLS validation failures
  • Client Closed Request — client disconnected before nginx sent the response

None of these codes are ever sent to browsers as real HTTP responses — they exist only in nginx's own access and error logs.

Opens the HTTP Status Code Reference with this page's reference values shown at the top of the tool.

Open in the tool →

When nginx returns 499: client disconnect

Nginx records 499 Client Closed Request in its access log when the client closes the TCP connection before nginx finishes sending the response.1 This most commonly occurs when the client's request timeout is shorter than the time your application takes to generate the response, which is why 499 spikes often correlate with the release of a slower code path or a new external dependency that adds latency to previously fast endpoints.

A high 499 rate often indicates that upstream application processing is too slow: clients time out and disconnect before receiving the response. 499 entries are correlated with poor user experience even though the response was eventually generated: the user or API client saw a timeout, not a successful response. The wasted upstream work also consumes application resources that could have been used for requests that clients actually received, so a sustained 499 spike can trigger a secondary resource exhaustion problem on the application tier.

Comparing the 499 timestamp with the upstream response time logged by nginx shows how long the application took to respond and how much it exceeded the client's timeout. Load balancers that sit in front of nginx also generate client disconnects for idle connections that exceed their idle timeout, so a 499 spike that correlates with a load balancer idle timeout configuration change is a strong signal that the timeout value is too aggressive for your application's actual response time distribution.

Using 444 to drop connections

Nginx's 444 No Response code is used in nginx configuration to instruct nginx to close the TCP connection immediately without sending any response.2 This is a security measure for blocking malicious requests, crawlers, or known bad IP addresses without giving them any information about the server. Because no bytes are sent on the connection, a client that receives a 444 cannot determine whether the server exists, what software it runs, or what endpoints are available, which reduces the information an attacker can gather during reconnaissance.

Common use cases for 444

A common pattern is using 444 in a server block for unknown Host headers: if a request arrives with no matching virtual host, nginx closes the connection with 444. It is also appropriate for rate-limiting specific IPs at the nginx level without revealing that the server exists, for blocking scanners by their User-Agent, or for discarding requests that match known attack probe URI patterns.

444 should not be used for legitimate requests that simply fail validation: those should receive standard 4xx responses that the client can act on. Dropping the connection on a legitimate client request wastes their time and makes debugging harder, because the client receives a generic connection error instead of a specific status code that points to the actual problem.

Reading nginx access logs for non-standard codes

Nginx access logs include the status code as the third field in the standard combined log format: the log line "GET /path HTTP/1.1" 499 0 shows a 499 with zero bytes sent. Filtering for non-standard codes reveals specific operational patterns that would otherwise be buried in the noise of standard status codes, and setting up a dedicated log format that captures $status, $upstream_response_time, and $request_time makes it possible to correlate non-standard codes with upstream latency in a single query.

Diagnosing non-standard code clusters

A cluster of 494 codes indicates that some clients are sending oversized request headers, often due to large cookies or custom headers from a misconfigured application.3 A cluster of 495 or 496 codes indicates SSL client certificate validation failures, which only appear if you have configured mutual TLS.4 Grouping non-standard codes by User-Agent, source IP, and request path in your log analysis tool reveals whether the failures are concentrated in a single client, a single endpoint, or a single time window, which determines whether the fix belongs in nginx configuration, application code, or infrastructure capacity planning.

499 codes that correlate with specific endpoints point to slow upstream handlers for those routes. 499 codes that correlate with specific time windows point to upstream latency spikes caused by database load, garbage collection, or external API slowdowns. Setting up nginx log parsing with separate counters for non-standard codes makes these patterns visible automatically in your monitoring system.

Tuning nginx buffers to prevent 494 Request Header Too Large errors

Nginx's large_client_header_buffers directive controls how nginx allocates memory for incoming request headers. The default configuration allows four 8 KB buffers (32 KB total). When a single header field or the combined headers exceed this limit, nginx returns 494 Request Header Or Cookie Too Large and rejects the request.5 Large cookies are the most common cause: modern web applications accumulate cookies from analytics tools, A/B testing platforms, and session managers, sometimes pushing the total cookie header size past nginx's default limit.

Large cookies from analytics tools, A/B testing platforms, and session managers sometimes push the total header size past nginx's 32 KB default buffer, which triggers 494 request header too large and rejects the request. Diagnosing the header causing the 494 requires examining the raw request headers nginx received before rejecting the request. After identifying the oversized header, increase large_client_header_buffers 8 16k in your http or server block to accommodate larger headers. Enable the underscores_in_headers on directive if your application uses custom headers with underscores, since nginx silently drops these by default, which can confuse debugging when expected headers are missing.

Balancing buffer size against memory usage

Each nginx worker process allocates large_client_header_buffers memory per connection when reading request headers. Increasing the buffer size multiplies the memory usage by the number of concurrent connections your server handles. For a server handling 10,000 concurrent connections with large_client_header_buffers 8 32k, each worker may allocate up to 256 KB per connection for header buffers alone. Profile your actual header sizes from production logs before increasing buffer limits, and set the minimum size needed rather than using an arbitrarily large value.

When to use this

Use this guide when interpreting nginx access logs and error pages. Reference it to identify what a non-standard nginx code means and which layer of the stack it implicates.

Examples

499 spike appearing in nginx logs after a new upstream service was deployed

The new upstream service is responding too slowly for the client timeout. Check the upstream response time in the nginx log (the last field in the combined format). Identify which endpoints are slowest and optimise the upstream handler or increase the client timeout if the latency is acceptable.

494 errors appearing in logs from a specific user agent

The client is sending request headers that exceed nginx's large_client_header_buffers limit. Either increase the buffer size in nginx.conf or investigate why the client is sending unusually large headers (common with large cookies from multiple frameworks sharing a domain).

Blocking a known scanner IP range at the nginx level

Use "return 444;" in a geo or if block for the scanner IP range. Nginx closes the connection without sending any response, preventing the scanner from getting information about the server version or available endpoints.

Sources
  1. 1.

    ServerFault, "Why does nginx always close the connection with return 444?," serverfault.com, accessed June 2026. https://serverfault.com/questions/1033849/why-does-nginx-always-close-the-connection-with-return-444

  2. 2.

    Nginx, "ngx_http_rewrite_module: return directive," nginx.org, accessed June 2026. https://nginx.org/en/docs/http/ngx_http_rewrite_module.html

  3. 3.

    Nginx, "ngx_http_core_module: large_client_header_buffers," nginx.org, accessed June 2026. https://nginx.org/en/docs/http/ngx_http_core_module.html

  4. 4.

    Mozilla Developer Network, "431 Request Header Fields Too Large," developer.mozilla.org, accessed October 2026. https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Status/431

  5. 5.

    Stack Overflow, "Nginx default error page is still showing," stackoverflow.com, accessed June 2026. https://stackoverflow.com/questions/61155938/nginx-default-error-page-is-still-showing

FAQ

The client closed the TCP connection before nginx finished sending the response. Most commonly: the client's request timeout is shorter than the time the upstream application took to respond. Also caused by load balancer idle timeouts and clients that cancel requests after clicking "stop" in the browser. High 499 rates indicate upstream latency issues.

No. Nginx records 499 in its own access log, but the browser never receives a 499 status code. From the browser's perspective, the connection was simply closed: it sees a network error or a timeout, not an HTTP response with a status code. The 499 is nginx's internal log code for accounting purposes.

444 instructs nginx to close the TCP connection immediately without sending any HTTP response at all. It is used in nginx configuration to silently drop malicious or unwanted connections. Legitimate HTTP clients receive no response and their connection is closed, preventing them from extracting any server information.

494 Request Header Or Cookie Too Large appears when the request headers exceed nginx's large_client_header_buffers size. Large cookies, long Authorization headers, or a misconfigured application appending custom headers can trigger it. Increase the large_client_header_buffers directive in nginx.conf or reduce the header size at the source.

495 SSL Certificate Error appears when the client presents an invalid SSL certificate during mutual TLS (mTLS) handshake. 496 SSL Certificate Required appears when nginx is configured to require a client certificate (ssl_verify_client on) but the client did not present one. Both only appear in mTLS configurations. CapyToolkit doesn't store or upload any data, so you can use its HTTP tools to verify your nginx configuration without exposing sensitive request logs to a third-party service.

Additional resources