Zum Hauptinhalt springen

Guides / http-status-codes

500 Internal Server Error: Causes, Logs and How It Differs From 502

A 500 Internal Server Error means the server hit an unexpected condition while handling the request and gave up, without saying what went wrong. It is the catch-all of the HTTP status codes, so the code itself carries almost no diagnostic value and the real answer is always in the logs.

Why 500 tells you so little

RFC 9110 defines 500 as an unexpected condition that prevented the server from fulfilling the request. That is deliberately broad. Anything the application did not anticipate, from a null reference to a failed database connection to a configuration file it cannot parse, ends up under the same number.

The vagueness is also a security feature. A 500 page should never leak stack traces, file paths, SQL fragments or library versions to the public, because those are exactly the details an attacker wants. So the code stays generic in the response, and the detail goes to a log only you can read. That trade is correct, and it makes one piece of knowledge more useful than any other: where your logs live.

500 versus 502, 503 and 504

All four are server errors, but they are produced by different components and point at different problems. Getting this right saves most of the debugging time.

  • 500 comes from the application itself. Something ran and threw. The application log has a stack trace.
  • 502 comes from a proxy in front of the application, which got an invalid response or a closed connection from the backend. The backend often logs nothing, because it never finished the request. See the 502 guide.
  • 503 is a refusal, not a crash. The server is overloaded or in maintenance and is declining work on purpose, usually with Retry-After.
  • 504 is a timeout. The backend was reachable but did not answer within the proxy's limit. The request is often still running behind the scenes.

A blunt shortcut: 500 means your code broke, 502 means your backend is dead or misbehaving, 503 means your server is saying no on purpose, 504 means your backend is too slow. The whole family is compared in the 5xx overview.

What causes a 500

  • Unhandled exceptions in application code. The largest single category. A null value, a failed type conversion, an array index out of range, a division by zero on a path nobody tested.
  • Database failures. Connection pool exhausted, credentials rotated, the database restarted, a query that deadlocks or times out.
  • Missing or broken dependencies after a deploy. A package that did not install, a file the build did not copy, an environment variable that exists in staging and not in production.
  • Configuration syntax errors. On Apache, a single invalid directive in an .htaccess file produces 500 for every request under that directory.
  • File permissions and ownership. The application cannot read a config file or write to a cache, session or upload directory.
  • Resource limits. A memory limit, an execution time limit or a full disk. These typically produce intermittent 500s that track with traffic.
  • Third-party API failures that the code calls without a fallback, so a remote outage becomes your error page.

How to diagnose a 500

  1. Confirm the code and who produced it. A branded error page can hide the real status:
    curl -sS -o /dev/null -D - https://example.com/failing-page
    Check the status line and any Server or CDN header. If the error is signed by an edge network and the origin answers 200, you are not looking at a 500 from your application at all.
  2. Open the application log first. This is where the stack trace is. Framework logs, the platform log stream or the container's stdout, whichever your stack uses, and match by timestamp and request path.
  3. Then the web server error log. Apache error_log, nginx error.log, or the Windows Event Log for IIS. If the application never logged anything, the failure happened before your code ran, which points at configuration or the runtime.
  4. Reproduce it deliberately. Establish whether the 500 affects one URL, one HTTP method, one user or everything. A 500 only on POST usually means form handling or a write path. A 500 for one user usually means their data.
  5. Turn on detailed errors in a non-public environment. Never on production. Reproduce in staging with full error output, which turns a generic 500 into a specific line number.
  6. Check what changed. The last deploy, a config push, a certificate renewal, a dependency update or a database migration. If the site was fine an hour ago, the answer is almost always in the last change.
  7. Check host resources. Disk space, memory and connection counts. A disk that filled with logs produces 500s that look completely unrelated to the code.

The 500s that only one page returns

Most 500s do not take the whole site down. One route, one form or one region breaks while the homepage keeps loading, so nothing looks wrong from the outside and the errors surface days later as lost signups. A scheduled HTTP check on the pages that matter, not only the homepage, compares the returned code against the expected one and alerts the moment a route starts answering 500. Alerts can arrive by email, SMS, voice call, Slack, Telegram and more, so a night-time failure reaches whoever is on call instead of waiting for the morning. HostTracker has been monitoring websites since 2004.

Check it now

Run the free check against your own site - no account needed.

HTTP check

Monitor this permanently

Get alerted the moment it breaks: HostTracker checks from 300+ locations and notifies you by email, SMS, Slack, Telegram and more.

HostTracker features