Código de status HTTP · Não oficial, usado por nginx
Erro 499 Client Closed Request
O 499 Client Closed Request é um código de log do nginx: o cliente fechou a conexão antes do nginx enviar a resposta. A causa mais comum é um backend mais lento que o timeout do próprio cliente: um balanceador, CDN, app ou usuário impaciente desistiu primeiro.
| Classe | 4xx/5xx, Códigos não oficiais (nginx, Cloudflare) |
|---|---|
| Definido em | nginx source: NGX_HTTP_CLIENT_CLOSED_REQUEST |
| Pode ir para o cache por padrão | Não; o cliente já foi embora antes de qualquer coisa ser enviada |
| Pode repetir o pedido | O cliente já desistiu; repetir só adianta se ele esperar mais ou o backend ficar mais rápido |
| Cabeçalhos relevantes | Nenhum específico deste código |
O que significa o 499
O código está definido no código-fonte do nginx como NGX_HTTP_CLIENT_CLOSED_REQUEST e nunca é enviado para ninguém: quando o nginx iria escrevê-lo, o socket já está fechado. Ele existe para o access log explicar um pedido que, sem isso, pareceria ter sumido.
Um 499 indica descompasso de timeouts com mais frequência do que bug. Se a Cloudflare na frente da sua origem para de esperar depois do timeout de leitura de 125 segundos, ou um load balancer tem timeout ocioso de 60 segundos, o nginx atrás dele registra 499 para cada pedido que demora mais, enquanto o visitante vê um 524 ou 504 vindo desse proxy da frente.
Por padrão o nginx também fecha a conexão com o upstream quando o cliente sai (proxy_ignore_client_abort off), então o backend pode ser interrompido no meio do trabalho. Ative essa diretiva só quando o processamento precisa terminar de qualquer jeito, como um callback de pagamento.
Causas comuns
Se você está visitando o site
- Você fechou a aba, apertou parar ou mudou de página enquanto ela ainda carregava.
- Uma conexão móvel instável caiu no meio do pedido, ou o app que você usa tem um timeout curto.
Se você administra o servidor
- O upstream (PHP-FPM, Node, uma consulta ao banco) demora mais que o timeout de quem está na frente do nginx: uma CDN, um load balancer de nuvem ou o padrão de uma biblioteca cliente.
- Health checks ou sondas de monitoramento com timeout de poucos segundos batendo num endpoint lento.
- Usuários clicando duas vezes, ou busca enquanto digita que cancela o fetch anterior com AbortController; isso é inofensivo e aparece como 499 de duração curta.
Como resolver
Se você está visitando o site
- Recarregue e espere a página terminar; se travar de novo, a lentidão é do lado do servidor.
Se você administra o servidor
- Registre $request_time e $upstream_response_time no log. Quando os 499 se concentram num valor (60 s, 100 s, 125 s), ele revela o timeout do componente na frente do nginx.
- Deixe o endpoint lento mais rápido, ou mande o trabalho longo para uma fila e responda 202 Accepted com uma URL de status para consulta.
- Ordene os timeouts de dentro para fora: backend menor que o proxy_read_timeout do nginx, que por sua vez é menor que o do load balancer ou CDN; assim a falha vira um 504 claro do nginx em vez de um 499.
- Não gere alerta para 499 curtos de fetch cancelado; é comportamento normal do cliente.
Como diagnosticar o 499
Você nunca envia 499; o nginx grava no access log quando o cliente desconecta. Os trechos abaixo mostram como registrar isso de forma útil e achar o padrão.
# 499 lands in $status; log timings to see who gave up first
log_format timing '$remote_addr "$request" $status '
'rt=$request_time urt=$upstream_response_time';
access_log /var/log/nginx/access.log timing;
location /api/ {
proxy_pass http://app;
proxy_read_timeout 60s;
# Optional: let the upstream finish even if the client leaves
# proxy_ignore_client_abort on;
}# Which URLs get the most 499s (default combined log: status is field 9)
awk '$9 == 499 {print $7}' /var/log/nginx/access.log | sort | uniq -c | sort -rn | head
# With the timing format above: how long did those requests run?
grep ' 499 rt=' /var/log/nginx/access.log | grep -o 'rt=[0-9.]*' | sort | uniq -c | sort -rn | headCostuma ser confundido com
- 499 vs 408
- No 408 o servidor desiste de um cliente lento demais para enviar o pedido; no 499 o cliente desiste de um servidor lento demais para responder.
- 499 vs 504
- O 504 é o próprio nginx estourando o tempo com o upstream e avisando o cliente; o 499 significa que o cliente saiu antes do nginx chegar ao próprio timeout.
- 499 vs 444
- O 444 é o nginx fechando a conexão de propósito; o 499 é o outro lado fechando.
Perguntas frequentes
- Erro 499 é problema no meu servidor?
- Muitas vezes sim, de forma indireta. Alguns 499 curtos são cancelamentos normais, mas muitos 499 com tempo alto indicam um backend mais lento que o timeout do cliente ou do proxy na frente do nginx.
- Por que vejo 499 no nginx mas 524 ou 504 no navegador?
- Algo entre o navegador e o nginx estourou o tempo antes. A Cloudflare mostra 524 depois do timeout de leitura de 125 segundos; um load balancer mostra 504. Esse proxy fecha a conexão com o nginx, que registra 499.
- O backend continua rodando depois de um 499?
- Por padrão o nginx fecha a conexão com o upstream, mas a maioria dos servidores de aplicação só percebe quando tenta escrever, então o trabalho costuma ir até o fim. Faça operações longas idempotentes ou mande para uma fila.
- Devo ativar o proxy_ignore_client_abort?
- Só em endpoints cujo trabalho precisa terminar mesmo que quem chamou vá embora. Ele mantém a conexão com o upstream aberta depois que o cliente desconecta; a resposta continua sem chegar a ninguém.
Revisado em por Arielton Oberek.