Skip to content

Código de status HTTP · Erros do servidor (5xx)

Erro 500 Internal Server Error

O erro 500 Internal Server Error significa que o servidor encontrou uma condição inesperada e não conseguiu concluir o pedido. É o código genérico para falhas do servidor, e a causa mais comum é uma exceção não tratada no código da aplicação: um valor nulo, uma consulta ao banco que falhou, uma variável de ambiente que faltou.

Dados sobre este código de status
Classe5xx, Erros do servidor
Definido emRFC 9110 §15.6.1
Pode ir para o cache por padrãoSó com Cache-Control ou Expires explícitos
Pode repetir o pedidoUma vez, talvez; um 500 causado por bug falha igual toda vez
Cabeçalhos relevantes
  • Content-Type: application/problem+json (RFC 9457) entrega ao cliente da API um erro legível por máquina sem vazar stack trace

O que significa o 500

A RFC 9110, seção 15.6.1, define o 500 numa frase só: o servidor encontrou uma condição inesperada que o impediu de atender o pedido. Não há significado mais específico que esse. É o padrão que a maioria dos frameworks usa quando o código lança uma exceção e ninguém trata: Express, route handlers do Next.js, FastAPI e Django transformam exceção não capturada em 500.

Por ser genérico, o código sozinho quase não diz nada sobre a causa. A informação útil está nos logs do servidor, no horário exato da requisição que falhou. O corpo da resposta deve continuar vago de propósito: stack trace ou erro de SQL exibido no navegador ajuda mais um atacante do que o usuário.

O 500 vem da própria aplicação, não de um proxy na frente dela. Se o nginx, o balanceador de carga ou a Cloudflare não conseguem nem falar com o seu app, o resultado é 502, 503, 504 ou um 52x. Ver um 500 é, na verdade, sinal de que o pedido chegou até o seu código.

Causas comuns

Se você está visitando o site

  • Um bug do site disparado pela página, pelo dado do formulário ou pela conta que você está usando; outras páginas podem funcionar normalmente.
  • Um deploy quebrado ou o banco de dados do site fora do ar, o que costuma afetar todo mundo ao mesmo tempo.
  • De vez em quando, um cookie de sessão antigo ou corrompido que o servidor não consegue interpretar.

Se você administra o servidor

  • Uma exceção não tratada: ler propriedade de undefined, um JSON.parse que falhou, um erro de tipo com um dado que você não esperava.
  • Uma dependência falhando durante o pedido: o banco recusa conexões, uma consulta estoura o tempo, uma API externa devolve algo que o código não trata.
  • Configuração que só falta em produção: variável de ambiente não definida, segredo errado, um caminho de arquivo que existe no seu notebook mas não no container.
  • Permissão errada em arquivos que a aplicação grava (uploads, cache, sessões), ou uma diretiva no .htaccess que o Apache não reconhece, que ele reporta como 500.
  • Um erro fatal do PHP ou estouro de memory_limit, que o PHP-FPM transforma em 500 com página em branco quando display_errors está desligado.

Como resolver

Se você está visitando o site

  • Recarregue uma vez. Se o 500 veio de uma instabilidade breve, como um deploy reiniciando a aplicação, a segunda tentativa costuma funcionar.
  • Tente outra página do mesmo site. Se só uma página ou uma ação falha, o bug é dela e só o dono do site resolve.
  • Se acontece apenas logado, saia da conta ou limpe os cookies daquele site e tente de novo.
  • Avise o site informando o horário e a URL; é exatamente o que o desenvolvedor precisa para achar o registro no log.

Se você administra o servidor

  • Leia o log da aplicação no horário da requisição que falhou, não o log do proxy: o stack trace está lá. Numa VPS, tente journalctl -u seu-app --since "10 min ago"; em PaaS, o visualizador de logs da plataforma.
  • Reproduza localmente com o mesmo dado, escreva um teste para o caso e corrija o trecho. Valide a entrada logo no início, para que dado ruim vire 400 ou 422 em vez de 500.
  • Compare a configuração de produção com o que o código espera: variável de ambiente faltando é o motivo mais comum de algo funcionar local e quebrar depois do deploy.
  • Registre um único tratador de erros que grave o erro completo com um ID da requisição e devolva um corpo genérico, assim todo 500 é rastreável e nada interno vaza.
  • Use monitoramento de erros (Sentry ou similar) e crie alerta para a taxa de 5xx, para saber dos 500 antes dos usuários reclamarem.

Como enviar um 500

Quase nunca você escreve status(500) na mão. O trabalho é capturar os erros inesperados num lugar só, registrar com contexto suficiente e responder com um corpo 500 genérico.

Express (Node.js)
app.get('/orders/:id', async (req, res) => {
  // Express 5 forwards a rejected promise here to the error handler
  const order = await db.orders.findById(req.params.id);
  res.json(order);
});

// Error handler: four arguments, registered after all routes
app.use((err, req, res, next) => {
  console.error(err);
  res.status(500).json({ error: 'Internal server error' });
});
Next.js App Router (route handler)
// app/orders/[id]/route.ts
export async function GET(
  _request: Request,
  { params }: { params: Promise<{ id: string }> }
) {
  const { id } = await params;
  try {
    return Response.json(await getOrder(id));
  } catch (err) {
    console.error(err);
    return Response.json({ error: 'Internal server error' }, { status: 500 });
  }
}
Go net/http
mux.HandleFunc("GET /orders/{id}", func(w http.ResponseWriter, r *http.Request) {
	order, err := store.Order(r.Context(), r.PathValue("id"))
	if err != nil {
		log.Printf("get order %s: %v", r.PathValue("id"), err)
		http.Error(w, "internal server error", http.StatusInternalServerError) // 500
		return
	}
	json.NewEncoder(w).Encode(order)
})
Python FastAPI
from fastapi import FastAPI, Request
from fastapi.responses import JSONResponse

app = FastAPI()

# Catch-all for exceptions nothing else handled
@app.exception_handler(Exception)
async def unhandled_error(request: Request, exc: Exception):
    return JSONResponse(status_code=500, content={"error": "Internal server error"})

Costuma ser confundido com

500 vs 502
O 500 é gerado pela própria aplicação; o 502 é gerado por um proxy ou gateway que recebeu uma resposta inválida, ou nenhuma, da aplicação atrás dele.
500 vs 503
O 503 é um "agora não" proposital, por sobrecarga ou manutenção, muitas vezes com Retry-After; o 500 é um acidente que o servidor não previu.
500 vs 400
Se um dado inválido derruba o handler, a resposta correta é 400 ou 422 depois da validação, não 500: o erro é do cliente, não do servidor.

Perguntas frequentes

Erro 500 é culpa minha ou do site?
Quase sempre do site. Um 500 significa que o servidor falhou ao processar um pedido que ele aceitou. A única coisa do seu lado que às vezes ajuda é limpar os cookies daquele site, caso a sessão corrompida seja o que derruba o servidor.
Como descobrir a causa de um erro 500?
Procure nos logs da aplicação no horário exato da requisição que falhou. A resposta HTTP é vaga de propósito; o stack trace, a consulta que falhou ou a variável ausente aparecem no log do servidor, na ferramenta de monitoramento de erros ou no painel de logs da hospedagem.
Minha API deve devolver 500 para erro de validação?
Não. Use 400 para pedido malformado e 422 para pedido bem formado com valores inválidos. Deixe o 500 para falhas que o cliente não poderia evitar, assim quem consome a API sabe se mudar o pedido resolve.
Erro 500 prejudica o SEO?
Um pico curto, não. O Googlebot diminui o ritmo de rastreamento quando vê muitas respostas 5xx, e páginas que continuam dando 500 por dias podem sair do índice. Corrigindo rápido, as páginas voltam a ser rastreadas normalmente.
Por que meu site mostra uma página em branco em vez de uma mensagem de erro?
PHP com display_errors desligado, e muitos builds de produção, mandam um 500 com corpo vazio de propósito. Confira o status na aba Rede do navegador e leia o log do PHP-FPM ou da aplicação para ver o erro real.

Revisado em por Arielton Oberek.