Error guide

500 Internal Server Error

The application hit an unhandled failure — the generic answer when nothing more specific applies.

A 500 Internal Server Error is the catch-all: the server encountered a condition it could not handle and had nothing more specific to say. In practice it almost always means an unhandled exception reached the top of the request handler, and the framework returned a 500 because there was nothing else it could do.

The response itself is deliberately uninformative, and rightly so — leaking a stack trace to the internet is a security problem. That means the response tells you essentially nothing, and the entire diagnosis lives in your own logs and error tracking.

The single most useful practice here is making each 500 correlatable. If the error page carries a request or trace identifier, and the same identifier appears in the log entry and in your error tracker, then a customer report and a stack trace can be joined in seconds instead of by guesswork over timestamps.

Common causes

  • An unhandled exception: a null reference, a failed type conversion, an unexpected response shape from a dependency.
  • A database connection failing, timing out, or the pool being exhausted.
  • A missing environment variable or configuration value after a deploy or an infrastructure change.
  • A dependency returning something the code did not anticipate, especially after that dependency changed.
  • Resource exhaustion — memory, disk, file descriptors — surfacing as errors in unrelated code paths.
  • A migration that ran partially, leaving code and schema disagreeing.

How to diagnose it

  1. Find the exception in the application log or error tracker: the stack trace is the answer, and nothing outside the server has it.
  2. Establish the blast radius — every request, one endpoint, or one class of input — which usually identifies the cause immediately.
  3. Check what changed at the start time: a deploy, a configuration change, a dependency's own incident.
  4. Verify dependency health directly rather than inferring it from your own errors.
  5. Check host-level resources; exhaustion produces 500s in places that look unrelated to the real problem.

Whose fault is it? The server's side

The server failed. A 500 caused by malformed input is still a server-side defect — input that cannot be handled should produce a 400, and reaching a 500 means it was not validated.

What monitoring sees

A 500 fails an Uptimely check by default and the code is recorded on the check. Because 500s are frequently intermittent — one bad input, one exhausted connection — the failure threshold matters here more than for most codes: the default of two consecutive failed checks means a single failing request does not page anyone while a sustained failure does.

Questions

How do I find the cause of a 500 error?

In your logs, not in the response. The response body is intentionally generic; the stack trace in your application log or error tracker is the actual answer. Carrying a request ID on the error page makes joining the two immediate.

What is the difference between 500 and 502?

A 500 comes from your application: it ran and threw. A 502 comes from a proxy in front of it: your application either did not answer or answered unintelligibly. They point at different layers.

One of the Uptimely HTTP and network error guides, written for the person who operates the server rather than the one refreshing the page. Something here read wrong to you? Email support@getuptimely.com.