Código de status HTTP · Erros do servidor (5xx)
Erro 504 Gateway Timeout
O erro 504 Gateway Timeout significa que um proxy ou gateway não recebeu resposta do servidor de trás a tempo e desistiu. A causa mais comum é um pedido lento na aplicação, como uma consulta pesada no banco ou uma chamada a uma API externa, que demora mais que o timeout do proxy (60 segundos por padrão no nginx).
| Classe | 5xx, Erros do servidor |
|---|---|
| Definido em | RFC 9110 §15.6.5 |
| Pode ir para o cache por padrão | Só com Cache-Control ou Expires explícitos |
| Pode repetir o pedido | Sim para pedidos idempotentes, com espera crescente; num POST, confira antes se a operação já aconteceu |
| Cabeçalhos relevantes |
|
O que significa o 504
A RFC 9110, seção 15.6.5, define o 504 como um gateway ou proxy que não recebeu a tempo a resposta de um servidor upstream de que precisava para concluir o pedido. Cada salto tem seu próprio relógio: CDN, balanceador, nginx e servidor da aplicação podem estourar o tempo, e quem perde a paciência primeiro é quem manda o 504.
Um 504 não significa que o trabalho parou. A aplicação pode continuar rodando a consulta ou concluindo o pagamento depois que o proxy já avisou o cliente da falha. Por isso repetir um POST às cegas depois de um 504 pode criar duplicatas, e operações longas devem responder 202 Accepted e rodar em segundo plano.
Vale conhecer os limites padrão. O nginx espera 60 segundos entre duas leituras do upstream (proxy_read_timeout) e no máximo 60 segundos para conectar (proxy_connect_timeout). Um Application Load Balancer da AWS devolve 504 quando não consegue conectar a um destino em 10 segundos ou quando o destino fica em silêncio além do idle timeout.
Causas comuns
Se você está visitando o site
- A página ou ação que você pediu dispara um trabalho lento no servidor, como um relatório grande, uma busca ou uma exportação.
- O backend do site ou um dos fornecedores dele está sobrecarregado e respondendo devagar para todo mundo.
- O site está atrás de uma CDN que não recebe a resposta do servidor de origem a tempo.
Se você administra o servidor
- Uma consulta lenta no banco, muitas vezes por falta de índice ou por lock de outra transação; o nginx registra "upstream timed out (110: Connection timed out) while reading response header from upstream".
- Uma chamada a uma API externa sem timeout próprio, então o pedido espera o quanto o fornecedor demorar.
- Um trabalho longo feito dentro da requisição (gerar relatório, processar arquivo, enviar centenas de e-mails) em vez de num worker em segundo plano.
- Timeout do proxy menor que o trabalho que você espera de fato, ou timeouts desencontrados entre camadas, por exemplo a Cloudflare esperando 125 segundos na frente de um nginx que desiste em 60.
- Problemas de rede entre proxy e aplicação: firewall descartando pacotes em silêncio, security group errado ou um nome DNS que resolve para um endereço inalcançável.
Como resolver
Se você está visitando o site
- Recarregue depois de um minuto; se o servidor só ficou sobrecarregado por um instante, a próxima tentativa costuma funcionar.
- Numa ação pesada, como uma exportação, tente um período menor ou menos itens.
- Antes de reenviar um pagamento ou pedido, confira seu e-mail ou sua conta: a primeira tentativa pode ter passado.
Se você administra o servidor
- Meça o pedido direto na aplicação, sem o proxy, para ver quanto tempo ele leva de verdade; depois investigue a parte lenta (plano da consulta com EXPLAIN, traces, slow query log).
- Defina timeout explícito em toda chamada externa, menor que o timeout do proxy, e devolva um erro claro quando ele disparar.
- Mande o trabalho longo para uma fila: responda 202 Accepted com uma URL de status e deixe o cliente consultar ou receber um webhook.
- Aumente o proxy_read_timeout só nas rotas que realmente precisam, e alinhe os timeouts para que as camadas de fora esperem um pouco mais que as de dentro.
- Se até a conexão falha, confira firewall, security groups e se o endereço do upstream na configuração do proxy é alcançável a partir do host do proxy.
Como enviar um 504
Como o 502, o 504 é produzido pelo proxy, não pelo seu handler. O exemplo em Go é para quando você mesmo escreve o gateway; o bloco do nginx aumenta o timeout só para uma rota lenta.
target, _ := url.Parse("http://127.0.0.1:9000")
proxy := httputil.NewSingleHostReverseProxy(target)
t := http.DefaultTransport.(*http.Transport).Clone()
t.ResponseHeaderTimeout = 30 * time.Second
proxy.Transport = t
// ReverseProxy answers 502 for every upstream error; report timeouts as 504
proxy.ErrorHandler = func(w http.ResponseWriter, r *http.Request, err error) {
var ne net.Error
if errors.As(err, &ne) && ne.Timeout() {
w.WriteHeader(http.StatusGatewayTimeout) // 504
return
}
w.WriteHeader(http.StatusBadGateway) // 502
}location /reports/ {
proxy_pass http://app;
proxy_connect_timeout 5s;
# Default 60s; a gap longer than this between reads becomes a 504
proxy_read_timeout 180s;
proxy_send_timeout 60s;
}# How long does the app take without the proxy?
curl -o /dev/null -s -w '%{http_code} %{time_total}s\n' http://127.0.0.1:3000/reports/annual
# Timeouts nginx recorded
grep 'upstream timed out' /var/log/nginx/error.log | tail -n 20Costuma ser confundido com
- 504 vs 502
- O 504 significa que o upstream ficou em silêncio tempo demais; o 502 significa que ele respondeu algo inválido ou derrubou a conexão.
- 504 vs 408
- O 408 Request Timeout é o servidor cansado de esperar o cliente terminar de enviar; o 504 é um proxy cansado de esperar outro servidor responder.
- 504 vs 524
- A Cloudflare informa o timeout da origem dela como 524, depois de conectar com sucesso e esperar 125 segundos por padrão, e não como 504.
- 504 vs 499
- Nos logs do nginx, 499 significa que o cliente desistiu antes do nginx; 504 significa que o nginx desistiu do upstream primeiro.
Perguntas frequentes
- Como resolver o erro 504 Gateway Timeout no nginx?
- Primeiro descubra por que o upstream está lento, medindo direto nele. Se a demora é legítima, aumente o proxy_read_timeout (e o fastcgi_read_timeout no PHP-FPM) só naquela location. Se não é, corrija a consulta lenta ou a chamada externa, ou leve o trabalho para um job em segundo plano.
- O erro 504 é problema da minha internet?
- Quase nunca. Seu pedido chegou ao proxy do site, tanto que você recebeu uma resposta. O tempo esgotou entre servidores, do lado do site.
- É seguro tentar de novo depois de um 504?
- Para GET e outros pedidos idempotentes, sim, com um intervalo. Num POST como um pagamento, o upstream pode ter concluído a operação depois que o proxy desistiu, então confira o resultado antes ou use uma chave de idempotência.
- Qual a diferença entre 504 e 408?
- O 408 Request Timeout significa que o servidor esperou demais o cliente mandar o pedido. O 504 Gateway Timeout significa que um proxy esperou demais um servidor upstream mandar a resposta.
- Por que o 504 aparece depois de exatamente 60 segundos?
- Sessenta segundos é o padrão do proxy_read_timeout e do fastcgi_read_timeout do nginx e do idle timeout do balanceador da AWS. Um 504 num número redondo quase sempre indica que um desses padrões foi atingido.
Revisado em por Arielton Oberek.