500 Internal Server Error: A Practical Guide to Finding the Real Cause
What Does This Error Mean?
A 500 Internal Server Error means your server crashed while handling the request — the generic status is deliberately vague to avoid leaking internals to the client. The real cause is almost always in the server logs, and finding it is a 5-minute job once you know where to look.
Step 1: Reproduce and Isolate
First, narrow it down: does it happen on one URL or every URL? One URL → the bug is in that route/handler. Every URL → middleware, database connection, or server config. Try the same request with a different method (GET vs POST) and with/without query params — each narrowing tells you which layer to inspect.
Step 2: Check the Logs (Fastest Path)
- Node/Express: the terminal or pm2 logs — look for the full stack trace printed after the 500
- Python/Django/Flask:
DEBUG=Truelocally shows the traceback in the browser; in production, check the configured log file or Sentry - PHP:
error_logsetting orphp -lfor syntax errors — checkdisplay_errorsin dev - Go:
log.Fatal/log.Printlnoutput, or the reverse proxy error log (nginx/apache) - Reverse proxy (nginx/apache): the 500 often comes FROM the proxy when the app crashes — check both app logs AND proxy error logs
Step 3: The Common Causes (Check These First)
- Database down or connection limit hit — check
SELECT 1manually; pool exhaustion looks like a 500 with a timeout in the log - Syntax/parse error in the deployed code — deploy a broken build and every request 500s
- Missing environment variable —
process.env.Xundefined at startup, often crashes on first request - Permission errors — the app can't write to its own temp/log/upload directory
- Out of memory — check the process for OOM kills; large request bodies can trip it
Step 4: Make the Error Visible (For Next Time)
If you hit a 500 with an empty log, your logging is broken — fix that first. Add request logging with a request ID, catch-all error middleware that logs the full stack with the request context, and an error tracking tool (Sentry, Rollbar) so the next 500 arrives in your inbox with a stack trace attached. The 500 is not a mystery — it's a log you haven't read yet.