503 Service Unavailable | Causas e Troubleshooting

Um erro 503 Service Unavailable indica que o servidor não pode lidar com a requisição devido a sobrecarga temporária ou manutenção. Aprenda causas, soluções e como implementar estratégias de retry adequadas.

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.

503 Service Unavailable

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ódigoSignificadoImplicação
503 Service UnavailableServidor não pode lidar com requisição agoraTemporário, tente mais tarde
502 Bad GatewayResposta inválida do upstreamUpstream crashou ou mal configurado
504 Gateway TimeoutUpstream não respondeuUpstream 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 upstream
if (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 Unavailable
Retry-After: 120
Content-Type: application/json
{
"error": "Serviço temporariamente indisponível",
"retryAfter": 120
}

Formatos de Retry-After

FormatoExemploSignificado
SegundosRetry-After: 120Tentar após 120 segundos
Data HTTPRetry-After: Fri, 26 Jun 2026 12:00:00 GMTTentar em horário específico

Estratégia de Retry do Cliente

Clientes devem:

  1. Verificar header Retry-After primeiro
  2. Usar backoff exponencial se não houver header
  3. Aplicar jitter para prevenir thundering herd
  4. 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

Terminal window
# Uso de CPU
top -bn1 | head -20
# Uso de memória
free -m
# Contagem de processos
ps aux | wc -l
# Contagem de conexões
ss -s

Passo 2: Verifique Logs da Aplicação

Terminal window
# Procure padrões de erro
grep -E "(503|overload|capacity|limit)" /var/log/app/error.log
# Verifique erros de out-of-memory
dmesg | grep -i "out of memory"

Passo 3: Verifique Dependências

Terminal window
# Conexões de banco de dados
netstat -an | grep :5432 | wc -l
# Conexões Redis
redis-cli INFO clients
# Status de API externa
curl -I https://api.example.com/status

Passo 4: Verifique Saúde do Load Balancer

Terminal window
# Stats HAProxy
curl http://localhost:8404/stats
# Status Nginx
curl http://localhost/nginx_status
# AWS ALB target health
aws 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 Events

Passo 5: Verifique Rate Limiting

Terminal window
# Status de rate limit Nginx
# Verifique logs limit_req
# Contadores de rate limit Redis
redis-cli GET rate_limit:client_ip

Como Corrigir Erros 503

Escalone Recursos

Adicione mais capacidade:

Terminal window
# Scaling horizontal Kubernetes
kubectl scale deployment app --replicas=10
# Adicione mais servidores ao pool
# Aumente tamanho da instância
# Adicione réplicas de leitura para banco

Implemente Rate Limiting

Proteja servidor de sobrecarga:

# Rate limiting Nginx
limit_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 custosas
const 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.

fique atualizado

Inscreva-se na nossa Newsletter

Receba as últimas atualizações de produtos, destaques de eventos e insights da indústria de tecnologia diretamente no seu e-mail.