Skip to content

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

Dados sobre este código de status
Classe5xx, Erros do servidor
Definido emRFC 9110 §15.6.5
Pode ir para o cache por padrãoSó com Cache-Control ou Expires explícitos
Pode repetir o pedidoSim para pedidos idempotentes, com espera crescente; num POST, confira antes se a operação já aconteceu
Cabeçalhos relevantes
  • Server: mostra qual proxy desistiu de esperar, para você saber qual timeout investigar

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.

Go net/http
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
}
Nginx
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;
}
Terminal
# 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 20

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