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.
| Classe | 5xx, Erros do servidor |
|---|---|
| Definido em | RFC 9110 §15.6.1 |
| Pode ir para o cache por padrão | Só com Cache-Control ou Expires explícitos |
| Pode repetir o pedido | Uma vez, talvez; um 500 causado por bug falha igual toda vez |
| Cabeçalhos relevantes |
|
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.
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' });
});// 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 });
}
}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)
})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.