Back to HTTP Status Codes

500 Internal Server Error 5xx

A generic error indicating the server encountered an unexpected condition and could not complete the request.

What does 500 mean?

A 500 Internal Server Error means something went wrong on the server while processing the request, but the server can't (or won't) say exactly what. Unlike 4xx errors, which point at a problem with the request, a 500 is the server's way of saying "this is on us" — though it's deliberately vague about what "this" actually is.

That vagueness is a feature, not a bug. Servers shouldn't leak internal details — stack traces, file paths, database schema, library versions — to anyone who can send a request. A 500 is the generic catch-all for "an unhandled exception occurred," and the actual details belong in server-side logs, not in the response sent to the client.

How a 500 behaves

  • It can carry a body — though what's in it varies wildly. In development, frameworks often show a full stack trace; in production, it should be a generic message ("Something went wrong") with no internal details exposed.
  • It's not cacheable by default. A 500 represents a transient failure (usually), so caching it would mean serving an error to users even after the underlying problem is fixed.
  • Retrying may or may not help. If the 500 was caused by a one-off bug (e.g., a null pointer on a specific edge case), retrying the exact same request will fail again. If it was caused by a transient issue (e.g., a brief database connection hiccup), a retry might succeed.
  • It's the default fallback. Most frameworks return 500 automatically when an unhandled exception bubbles up — you usually don't return it explicitly; it's what happens when nothing else catches the error.

Common causes

If you're building the API or website:

  • An unhandled exception in application code — null references, type errors, division by zero, array index out of bounds
  • A database connection failure, query syntax error, or constraint violation that wasn't caught
  • A missing environment variable or misconfigured .env file in production
  • A third-party service/dependency timing out or returning unexpected data that your code doesn't handle gracefully
  • File permission issues — the application can't write to a log directory, cache directory, or upload folder
  • Running out of memory or hitting a PHP/Node/Python execution time limit mid-request

If you're calling an API:

  • The API itself has a bug triggered by your specific input — sometimes a particular combination of parameters that the API author didn't test
  • You're hitting an endpoint during a deploy or maintenance window where the server is in a half-updated state
  • A payload that's technically valid JSON/XML but contains a value the server-side code doesn't expect (e.g., a string where a number was assumed)

If you're a website visitor:

  • The site is experiencing a temporary outage or bug
  • You triggered an edge case — e.g., submitting a form with an unusual character, very long input, or at a specific timing that exposed a race condition

How to fix it

As an API/website builder:

  • Check your error logs first — this is non-negotiable. The 500 response tells the client nothing; your logs (Laravel's storage/logs/laravel.log, or your platform's equivalent) tell you everything
  • Reproduce the exact request that caused it — same headers, same payload, same auth state
  • Wrap risky operations (external API calls, file I/O, database queries) in proper error handling so a single failure doesn't crash the whole request
  • Set up error monitoring (Sentry, Bugsnag, or similar) so you find out about 500s before users report them
  • Never display raw stack traces or debug information in production — disable debug mode (APP_DEBUG=false in Laravel) on live environments

As an API consumer:

  • Retry with exponential backoff — a small number of retries can smooth over transient 500s, but don't retry indefinitely
  • If the 500 happens consistently with a specific payload, simplify the payload to isolate which field or value triggers it, then report it to the API provider
  • Check the API's status page — many providers publish real-time incident status for widespread 500s

As a website visitor:

  • Refresh the page — many 500s are transient
  • Try again in a few minutes — the site owner may already be aware and fixing it
  • If it persists, the issue is on the site's end; there's nothing to fix on your side

500 vs related codes

Code Meaning Key difference from 500
502 Bad Gateway A server acting as a gateway/proxy got an invalid response from an upstream server 502 is specifically about a broken handoff between servers; 500 is about the application itself failing
503 Service Unavailable The server is temporarily unable to handle requests (overload, maintenance) 503 is often deliberate and temporary (and ideally includes a Retry-After header); 500 is usually an unplanned bug
504 Gateway Timeout A gateway/proxy didn't get a response from the upstream server in time 504 is about waiting too long; 500 is about the response itself being an error
400 Bad Request The client sent a malformed request 400 is the client's fault; 500 is explicitly the server's fault

Real-world examples

Stripe's API documentation explicitly tells developers that a 500 means "something went wrong on Stripe's end" and recommends retrying the request — a good model for how to communicate this code to API consumers. Cloudflare-fronted sites sometimes show a generic Cloudflare error page for a 500 originating from the origin server, which can make it harder to tell whether the problem is the CDN or the application — checking the origin server directly (bypassing Cloudflare) is a common debugging step in exactly this situation.

SEO implications

A 500 error on a page that search engines try to crawl is treated as a signal that the page is temporarily unavailable. If it's a one-off, search engines will simply retry later with minimal impact. However, if a significant portion of your site returns 500s during a crawl, it can cause search engines to slow down their crawl rate ("crawl budget" gets deprioritized) and, in extreme or prolonged cases, pages may be temporarily removed from the index until they become accessible again.

Unlike a 404 (which clearly says "this doesn't exist"), a 500 doesn't give search engines a clear signal about whether the page is permanently broken or just having a bad moment — so prolonged 500s are worse for SEO than a clean 404 for content that's genuinely gone.

FAQ

Is a 500 error always a bug?

Usually, yes — a 500 means an unhandled exception or unexpected condition occurred in server-side code. It's different from 503, which can be a deliberate, planned response (e.g., during maintenance).

Why doesn't the server tell me what went wrong?

Security and good practice. Detailed error messages can leak sensitive information — file paths, database structure, library versions — that could help an attacker. Production environments should show a generic message while logging the real details server-side.

Should I retry a request that returned a 500?

It depends. If the failure was caused by bad input or a code bug, retrying the identical request will fail again. If it was caused by a transient issue (a brief database hiccup, a momentary resource spike), a retry — ideally with a short delay — might succeed.

Can a 500 error happen on a perfectly fine website?

Yes, occasionally. Even well-maintained sites can hit edge cases — unexpected input, a sudden spike in traffic, a third-party dependency going down. A single 500 isn't necessarily a sign of a poorly built site; a pattern of frequent 500s usually is.

What's the difference between 500 and a browser-level error?

A 500 is generated by the server and sent as an HTTP response — the server is reachable and responding, just with an error. A browser-level error (like "This site can't be reached") means the request never got a response at all, which points to a network, DNS, or server-availability issue rather than an application bug.

Fun fact

The HTTP/1.0 spec originally defined only a handful of status codes, and 500 was one of the first server-error codes ever defined — it's been the universal "something broke" signal since 1996, predating most of the web frameworks that rely on it today.

Related Status Codes