Um erro 503 Service Unavailable indica que o servidor está temporariamente incapaz de lidar com a requisição. Diferente de 500 (erro inesperado) ou 502 (bad gateway), 503 sinaliza especificamente uma condição temporária que pode se resolver—tipicamente sobrecarga, manutenção ou esgotamento de recursos. Dentro da classe 5xx dos códigos de status HTTP, o 503 é único porque instrui explicitamente os clientes a tentar novamente mais tarde.

O Que Significa 503 Service Unavailable
A Definição HTTP
Per a RFC 9110, 503 indica “o servidor está atualmente incapaz de lidar com a requisição devido a uma sobrecarga temporária ou manutenção agendada, que provavelmente será aliviada após algum atraso.”
Características principais:
- A condição é temporária
- Clientes devem tentar novamente após um atraso
- A resposta deve incluir header
Retry-After - O erro é do lado do servidor, não culpa do cliente
503 vs 502 vs 504
| Código | Significado | Implicação |
|---|---|---|
| 503 Service Unavailable | Servidor não pode lidar com requisição agora | Temporário, tente mais tarde |
| 502 Bad Gateway | Resposta inválida do upstream | Upstream crashou ou mal configurado |
| 504 Gateway Timeout | Upstream não respondeu | Upstream muito lento |
Causas Comuns de 503 Service Unavailable
1. Sobrecarga do Servidor
O servidor tem mais requisições do que pode lidar:
- CPU a 100%
- Memória esgotada
- Pool de conexões cheio
- Pool de threads esgotado
2. Manutenção Agendada
O serviço foi intencionalmente tirado do ar:
- Deploys e atualizações
- Migrações de banco de dados
- Upgrades de infraestrutura
- Mudanças de configuração
3. Esgotamento de Recursos
Dependências externas indisponíveis:
- Pool de conexões de banco esgotado
- Rate limits de API terceira atingidos
- Cota de armazenamento excedida
- Limites de descritores de arquivo atingidos
4. Aplicação Não Pronta
A aplicação não terminou de iniciar:
- Health check falha durante startup
- Período de warm-up incompleto
- Dependências não inicializadas
5. Circuit Breaker Aberto
Um padrão de resiliência bloqueando requisições:
// Circuit breaker aberto devido a falhas upstreamif (circuitBreaker.open) { return res.status(503).json({ error: 'Serviço temporariamente indisponível' });}O Header Retry-After
A resposta 503 deve incluir um header Retry-After:
HTTP/1.1 503 Service UnavailableRetry-After: 120Content-Type: application/json
{ "error": "Serviço temporariamente indisponível", "retryAfter": 120}Formatos de Retry-After
| Formato | Exemplo | Significado |
|---|---|---|
| Segundos | Retry-After: 120 | Tentar após 120 segundos |
| Data HTTP | Retry-After: Fri, 26 Jun 2026 12:00:00 GMT | Tentar em horário específico |
Estratégia de Retry do Cliente
Clientes devem:
- Verificar header
Retry-Afterprimeiro - Usar backoff exponencial se não houver header
- Aplicar jitter para prevenir thundering herd
- Desistir após máximo de retries
async function fetchWithRetry(url, maxRetries = 3) { for (let i = 0; i < maxRetries; i++) { const response = await fetch(url);
if (response.ok) return response;
if (response.status === 503) { const retryAfter = response.headers.get('Retry-After'); const delay = retryAfter ? parseInt(retryAfter) * 1000 : Math.pow(2, i) * 1000 + Math.random() * 1000;
await sleep(delay); continue; }
throw new Error(`HTTP ${response.status}`); }
throw new Error('Máximo de retries excedido');}Troubleshooting de Erros 503
Passo 1: Verifique Métricas do Servidor
# Uso de CPUtop -bn1 | head -20
# Uso de memóriafree -m
# Contagem de processosps aux | wc -l
# Contagem de conexõesss -sPasso 2: Verifique Logs da Aplicação
# Procure padrões de errogrep -E "(503|overload|capacity|limit)" /var/log/app/error.log
# Verifique erros de out-of-memorydmesg | grep -i "out of memory"Passo 3: Verifique Dependências
# Conexões de banco de dadosnetstat -an | grep :5432 | wc -l
# Conexões Redisredis-cli INFO clients
# Status de API externacurl -I https://api.example.com/statusPasso 4: Verifique Saúde do Load Balancer
# Stats HAProxycurl http://localhost:8404/stats
# Status Nginxcurl http://localhost/nginx_status
# AWS ALB target healthaws elbv2 describe-target-health --target-group-arn arn:...
# Azion: verifique saúde da origem em Real-Time Metrics → Edge Application → Status Codes# Filtre por 503 e correlacione com o campo upstream_status no Real-Time EventsPasso 5: Verifique Rate Limiting
# Status de rate limit Nginx# Verifique logs limit_req
# Contadores de rate limit Redisredis-cli GET rate_limit:client_ipComo Corrigir Erros 503
Escalone Recursos
Adicione mais capacidade:
# Scaling horizontal Kuberneteskubectl scale deployment app --replicas=10
# Adicione mais servidores ao pool# Aumente tamanho da instância# Adicione réplicas de leitura para bancoImplemente Rate Limiting
Proteja servidor de sobrecarga:
# Rate limiting Nginxlimit_req_zone $binary_remote_addr zone=api:10m rate=10r/s;
location /api/ { limit_req zone=api burst=20 nodelay;}Adicione Circuit Breakers
Previna falhas em cascata:
const CircuitBreaker = require('opossum');
const breaker = new CircuitBreaker(callExternalService, { timeout: 5000, errorThresholdPercentage: 50, resetTimeout: 30000});
breaker.fire() .catch(() => { // Retorne fallback ou 503 res.status(503).json({ error: 'Serviço temporariamente indisponível' }); });Implemente Enfileiramento
Enfileire requisições em vez de rejeitar:
// Use uma fila para operações custosasconst queue = new Queue('processamento');
app.post('/api/process', async (req, res) => { const job = await queue.add(req.body); res.status(202).json({ jobId: job.id });});Degradação Graciosa
Retorne respostas cacheadas ou simplificadas:
app.get('/api/products', async (req, res) => { try { const products = await getProducts(); res.json(products); } catch (error) { // Retorne produtos cacheados se disponíveis const cached = await cache.get('products:fallback'); if (cached) { return res.json(cached); } res.status(503).json({ error: 'Serviço temporariamente indisponível' }); }});Perguntas Frequentes
Qual a diferença entre 503 e 502? 503 significa que o servidor está temporariamente sobrecarregado ou em manutenção. 502 significa que o proxy recebeu uma resposta inválida do upstream.
Devo tentar novamente em 503? Sim, 503 é explicitamente retryable. Verifique o header Retry-After para orientação.
Quanto tempo deve ser Retry-After? Depende da causa: manutenção (horário de fim conhecido), sobrecarga (30-120 segundos típico), circuit breaker (tempo de reset configurado).
Posso usar 503 para rate limiting? 429 Too Many Requests é mais apropriado para rate limiting. Use 503 para problemas de capacidade do lado do servidor.
Como testo tratamento de 503? Retorne intencionalmente 503 em ambiente de teste, ou use ferramentas de chaos engineering para simular sobrecarga.
O que acontece se Retry-After estiver ausente? Use backoff exponencial com jitter: 1s, 2s, 4s, 8s, etc., com jitter aleatório adicionado.