Skip to content

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.

Dados sobre este código de status
Classe4xx/5xx, Códigos não oficiais (nginx, Cloudflare)
Definido emnginx source: NGX_HTTP_CLIENT_CLOSED_REQUEST
Pode ir para o cache por padrãoNão; o cliente já foi embora antes de qualquer coisa ser enviada
Pode repetir o pedidoO cliente já desistiu; repetir só adianta se ele esperar mais ou o backend ficar mais rápido
Cabeçalhos relevantesNenhum 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.

Nginx
# 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;
}
Terminal
# 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 | head

Costuma 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.