500 Internal Server Error
500 Internal Server Error means the server hit an unexpected condition, usually an unhandled exception, and has no more specific code to give. The cause is in the server's logs, not in the response.
Something went wrong on the server, and it has no more specific code to report.
Almost always an unhandled exception or crash in application code; the detail is in the server's error log, not the response. Clients cannot fix it by changing the request, though retrying idempotent requests can help with transient faults. Do not return stack traces in a 500 body in production.
Explained
If the server is yours, the response body rarely helps: production frameworks hide details on purpose. The stack trace is in the application log, the error tracker (Sentry and the like), or the web server's error log.
500 comes from the server that ran the code. If a proxy sits in front, a crash in the app usually reaches the client as a 500 only if the app managed to send a response. If the app process died or never answered, the proxy reports 502 or 504 instead.
With PHP-FPM or Apache, a 500 with an empty body often means a fatal error before output started, or a syntax error in .htaccess. Check the web server error log first in those setups.
How to debug it
- Find the request in the application log by time, path or request ID, and read the exception.
- Reproduce with the same input; 500s triggered by specific data (a null field, an unexpected encoding) are common.
- Check what changed recently: deploys, config, environment variables, database migrations.
- Check dependencies the code calls: database connection limits, a downstream API returning errors, a full disk.
- If there is no log entry at all, the failure happened before your code ran: check the web server or runtime log.
Gotchas
- Turning on debug mode in production to see the error also exposes stack traces and settings to every visitor.
- Returning 500 for bad input hides client mistakes as server faults; validate input and return 400 or 422.
- Retries are only safe for idempotent requests; retrying a POST that failed halfway can duplicate work.
Related explainers
- 502 Bad GatewayA 502 means a proxy got no valid reply from the app behind it. How to read nginx's error log, common...
- 503 Service Unavailable503 means the server is temporarily unable to handle requests. Common sources: no healthy backends, nginx...
- 504 Gateway TimeoutA 504 means a proxy waited too long for the app behind it. Which timeout fired (nginx proxy_read_timeout,...