---
title: 500 Internal Server Error
description: What HTTP 500 means, the usual suspects from unhandled exceptions to bad deploys, and how to catch them before your users report them.
canonical: https://watchfor.io/docs/reference/http-status-codes/500
---

# 500 Internal Server Error

What HTTP 500 means, the usual suspects from unhandled exceptions to bad deploys, and how to catch them before your users report them.

**500 Internal Server Error** is the server's catch-all confession: the request
was fine, but something inside broke while handling it. An unhandled exception,
a crashed process, a dependency that misbehaved — anything the code didn't
anticipate ends up as a 500.

## Common causes

- **Unhandled exceptions** — null references, type errors, panics; the
  request hit a code path nobody tested
- **Database trouble** — connection pool exhausted, migrations out of sync
  with the code, a query timing out and surfacing as an exception
- **Bad deploys** — missing environment variables, broken config, a
  dependency version mismatch that only explodes at runtime
- **Downstream failures without handling** — a third-party API call throws,
  and instead of degrading gracefully the whole request 500s
- **Resource exhaustion** — out of memory, out of file descriptors, disk full
  (logs and temp files are the usual culprits)
- **Permission and filesystem errors** — the app can't write where it expects
  to (see [403](/docs/reference/http-status-codes/403) for the web-server
  variant)

## Intermittent vs constant

- **Every request 500s** → deploy or dependency-wide failure; roll back first,
  diagnose second.
- **Some requests 500** → data-dependent bug (one user's record, one input
  shape) or one bad instance behind the load balancer.
- **Bursts of 500s** → resource exhaustion cycles, restart loops, or a
  downstream dependency flapping.

## Debugging

The response body is deliberately generic (leaking stack traces is a security
hole), so the truth lives in your logs and error tracker — correlate by
timestamp and request ID. Reproduce with the free
[API tester](/api-tester) to confirm which exact input triggers it.

Because 500s are precisely the thing you never want users to find first, this
is the code most worth monitoring for: an [HTTP monitor](/docs/monitors/web)
alerts on any 5xx by default, and
[multi-region confirmation](/docs/alerting/incidents) separates "one flaky
request" from "the service is broken". Pair it with
[response-time tracking](/docs/monitors/performance) — 500s are often preceded
by minutes of degrading latency.

---

Canonical page: https://watchfor.io/docs/reference/http-status-codes/500 · All docs: https://watchfor.io/docs · Site guide: https://watchfor.io/llms.txt
