5xx errors: what they mean and how to catch them
5xx errors are HTTP responses that say the server failed to handle a request that looked valid. The request was fine; something on your side broke. The app crashed, timed out, was not listening, or the proxy in front of it could not reach it.
On an app platform such as Railway, Render or Vercel, most 5xx errors come from the platform’s proxy, reporting that your app did not answer.
What a 5xx server error means
HTTP status codes come in five classes, set by the first digit. Only 5xx says the fault is on the server.
| Class | Meaning | Who usually fixes it |
|---|---|---|
| 1xx | Informational: the request is still in progress | Nobody |
| 2xx | Success | Nobody |
| 3xx | Redirect to another URL | Usually nobody |
| 4xx | The request was wrong: bad input, missing login, page not found | The client, or your routing |
| 5xx | The server failed a valid request | You |
4xx vs 5xx errors
A 4xx is the client’s fault: a broken link (404), a missing login (401) or too many requests (429). A rise in 4xx is worth a look, but it rarely means your app is down.
A 5xx is your fault: the same request would work if the server were healthy. That is why error-rate alerts count 5xx and leave 4xx out.
One exception is 499 status code. It is not an official code, but nginx and the proxies built on it log it when the client gave up before the server answered. A run of 499s usually means your app is too slow, so Opyntel counts 499 with 5xx as errors.
The common 5xx codes on an app platform
| Code | Name | What it usually means behind a platform proxy | Guide |
|---|---|---|---|
| 500 | Internal Server Error | Your code threw an unhandled exception. Check the app’s logs at that time. | |
| 502 | Bad Gateway | The proxy could not get a valid answer from your app: it is not listening on the expected port, it crashed mid-request, or it was restarting. | 502 Bad Gateway |
| 503 | Service Unavailable | No healthy instance to send the request to: the service is starting, scaling, sleeping or overloaded. | 503 Service Unavailable |
| 504 | Gateway Timeout | Your app took longer than the proxy’s time limit. Common on long API calls and serverless functions. | 504 Gateway Timeout |
| 520 to 526 | Cloudflare origin errors | Cloudflare reached your origin but got an empty or bad answer (520), could not connect (521, 522, 523), timed out (524) or failed TLS (525, 526). | Cloudflare 5xx errors |
Why the platform’s error page is not enough
A single 502 can be a deploy in progress. What matters is the share of requests failing over a few minutes: the error rate. A service that fails 1 request in 1,000 is healthy; one that fails 1 in 10 for ten minutes is losing users.
Most app platforms chart status codes per service. Few alert on the error rate without an enterprise plan or a paid add-on, and none show it across the other platforms you run. Netlify, for example, shows server errors in its observability view but leaves alerting to a log drain and a third-party tool.
How to find the cause of a 5xx
- Find when it started. Open the service’s HTTP metrics or status-code chart and find the first minute the 5xx line rose.
- Match it to a change. A deploy, a config change or a traffic spike at that minute is the usual cause.
- Read the logs at that minute. Look for a crash, an out-of-memory kill (exit code 137), a timeout or a refused database connection.
- Check the port and host. A 502 on every request right after a deploy usually means the app listens on the wrong port, or on localhost instead of
0.0.0.0. - Check memory and CPU. Intermittent 502s and 504s often follow a service hitting its memory limit or pinning its CPU.