500 Internal Server Error
The server hit an unexpected condition and could not complete the request.
What 500 means
500 is the server admitting an unhandled failure: an exception escaped, an assertion failed, something was null that should not have been. It is not a description of the problem so much as an acknowledgement that there is one, which is why the useful information is always in your logs rather than in the response.
The important discipline is not collapsing every server-side failure into 500. A 502 means an upstream returned something unusable, 503 means you are deliberately refusing work, and 504 means an upstream did not answer in time. Those point at completely different causes, and using 500 for all four throws away the most useful signal you have during an incident.
500 responses must not leak internals. A stack trace in the response body reveals framework versions, file paths and sometimes credentials, and it is a genuine information-disclosure finding in a security review. Return an opaque error with a correlation ID and keep the detail server-side.
That correlation ID is worth the small effort: it lets a user report 'I got error abc123' and lets you find the exact request in your logs without guessing.
Common causes of a 500
- An unhandled exception in application code.
- A database connection failure or exhausted connection pool.
- A null or undefined value reaching code that assumed otherwise.
- A missing environment variable or configuration value at runtime.
- Out-of-memory conditions killing the worker mid-request.
- A failed deployment leaving the application in an inconsistent state.
- An unhandled promise rejection or a panic in a request handler.
How to fix a 500
- Read the server logs - the response body cannot tell you anything useful by design.
- Return a correlation ID in the response and log it, so user reports map to specific requests.
- Never return stack traces to clients; that is an information-disclosure issue.
- Distinguish 502, 503 and 504 rather than returning 500 for every server-side failure.
- Check whether the failure correlates with a deployment, a traffic spike, or a dependency's incident.
Should a client retry?
Often transient, so retry with exponential backoff and jitter - but cap the attempts. A retry storm against an already-failing server prolongs the outage.
FAQ
- How do I debug a 500?
- In the server logs. The response is deliberately opaque, so the stack trace, the failing query and the correlation ID all live server-side. Returning a correlation ID to the client is what connects a user's report to a specific log entry.
- Should a client retry a 500?
- Usually yes, with exponential backoff and jitter, since many causes are transient. Cap the attempts - unbounded retries against a struggling server turn a partial failure into an outage.
- 500 or 503?
- 500 means something broke unexpectedly. 503 means you are deliberately declining work - overloaded, in maintenance, a dependency down. 503 is a much clearer signal, and it can carry Retry-After.
- Is it safe to return the error message in the response?
- No. Stack traces and exception messages leak file paths, framework versions, SQL fragments and occasionally credentials. Return an opaque message plus a correlation ID.
Often confused with
- 502 Bad Gateway A server acting as a gateway received an invalid response from an upstream server.
- 503 Service Unavailable The server is temporarily unable to handle the request - overloaded or down for maintenance.