Your monitoring dashboard lights up red at 2 AM. The alert says your checkout page returned a 403. You scramble out of bed, SSH into the server, check the logs -- everything looks fine. The app is running, the database is connected, no errors in sight. Thirty minutes later you realize it was Cloudflare's WAF blocking the monitoring request because it looked like a bot. The site was never down. You just lost sleep over a status code you did not understand.

HTTP status codes are the language your server speaks when a monitoring tool checks on it. Understanding that language is the difference between catching real outages and chasing false alarms. This guide breaks down every status code family, explains which codes actually matter for uptime monitoring, and covers the gotchas that trip up even experienced engineers. If you are new to monitoring entirely, our introduction to uptime monitoring covers the fundamentals.

The five status code families

HTTP status codes are three-digit numbers grouped into five families. The first digit tells you the category. Here is what each family means in practice.

1xx -- Informational

These are handshake codes. 100 Continue tells a client it can proceed with sending a request body. 101 Switching Protocols is used during WebSocket upgrades. You will almost never see 1xx codes in uptime monitoring because they are transient -- the server sends them mid-conversation, not as a final response. If your monitor reports a 1xx code, something unusual is happening with the connection and it is worth investigating.

2xx -- Success

The family you want to see. A 2xx code means the server received the request, understood it, and processed it successfully.

  • 200 OK -- the standard success response. The request worked and the response body contains the result.
  • 201 Created -- a resource was successfully created. Common on POST endpoints in REST APIs.
  • 204 No Content -- the request succeeded but there is no response body. Typical for DELETE endpoints or health checks that do not return data.

For uptime monitoring, 200 is the default expected code. But if you are monitoring API endpoints, you might need to expect 201 or 204 depending on the endpoint's design.

3xx -- Redirection

The server is telling the client to look elsewhere.

  • 301 Moved Permanently -- the URL has permanently moved. Browsers and crawlers should update their records.
  • 302 Found -- temporary redirect. The original URL is still valid, but the content is temporarily at another location.
  • 304 Not Modified -- the resource has not changed since the last request. Used with caching headers.
  • 307 Temporary Redirect -- like 302, but explicitly preserves the HTTP method. A POST stays a POST.
  • 308 Permanent Redirect -- like 301, but preserves the HTTP method.

Redirects are where many monitoring setups go wrong. More on that in the gotchas section below.

4xx -- Client errors

The server is telling the client that the request was wrong. From a monitoring perspective, some 4xx codes indicate configuration problems with your monitor, while others indicate real issues with your site.

  • 400 Bad Request -- the request was malformed. If your monitor gets this, check your request body or headers.
  • 401 Unauthorized -- authentication is required but was not provided or is invalid.
  • 403 Forbidden -- the server understood the request but refuses to authorize it. Often comes from firewalls, WAFs, or permission changes.
  • 404 Not Found -- the URL does not exist on the server.
  • 405 Method Not Allowed -- you sent a POST to an endpoint that only accepts GET, or vice versa.
  • 408 Request Timeout -- the server timed out waiting for the client to finish sending the request.
  • 429 Too Many Requests -- rate limiting. The client has sent too many requests in a given time window.

5xx -- Server errors

These are the codes that mean something is genuinely broken on the server side. A 5xx response from your uptime monitor almost always warrants investigation.

  • 500 Internal Server Error -- a generic "something went wrong" on the server. The most common server error.
  • 502 Bad Gateway -- a reverse proxy or load balancer got an invalid response from an upstream server.
  • 503 Service Unavailable -- the server cannot handle the request right now, usually due to overload or maintenance.
  • 504 Gateway Timeout -- a reverse proxy or load balancer timed out waiting for a response from an upstream server.

Status codes that matter most for uptime monitoring

Not all status codes deserve the same attention. Here are the ones you will encounter regularly when monitoring web services, and what each one tells you about the health of your infrastructure.

200 OK -- the baseline

This is what your monitor expects to see in the vast majority of cases. A 200 means the server processed the request and returned content. For web pages, this means the HTML rendered. For APIs, it means the endpoint responded with data. When you set up a monitor, 200 is the default expected status code.

But 200 alone is not proof that everything is working. A server can return a 200 with a completely broken page, an error message, or zero data. That is why keyword monitoring exists -- to verify the response body actually contains what it should.

301 and 302 -- redirects that confuse monitors

If your monitor checks http://example.com and the server redirects to https://example.com, the monitor sees a 301, not a 200. Whether this triggers an alert depends on your monitoring tool's behavior.

Some tools follow redirects automatically and report the final status code. Others report the first response they receive. In CronAlert, if you set the expected status code to 200 and the server responds with a 301, that is treated as a failure. The fix is simple: update your monitor URL to use the final destination URL directly. Monitor https://example.com instead of http://example.com.

403 Forbidden -- firewalls and false alarms

A 403 from your uptime monitor usually means one of three things: a WAF (Web Application Firewall) is blocking the request, a CDN is rejecting the monitor's IP or user agent, or someone changed permissions on the resource. This is the most common source of false positives in uptime monitoring.

If your site is fine but your monitor keeps getting 403s, check whether your CDN or WAF has bot protection that is flagging the monitoring requests. You may need to allowlist the monitoring service's IP range or user agent.

404 Not Found -- URL changes and broken deployments

A 404 on a URL that was previously returning 200 means something changed. Either the page was removed, the URL structure changed during a deployment, or a routing configuration broke. This is a real issue that needs attention -- your users are seeing the same 404.

500 Internal Server Error -- the catch-all crash

A 500 means the server hit an unhandled exception. It could be a database connection failure, a null pointer, a failed dependency, or any number of application-level bugs. This is almost always a real outage. Check your application logs immediately.

502 Bad Gateway -- the process is dead

A 502 typically means your reverse proxy (Nginx, Cloudflare, an AWS ALB) tried to forward the request to your application, but the application process was not running or returned garbage. Common causes: the app crashed, a deployment restarted the process, or the application ran out of memory and was killed by the OS.

503 Service Unavailable -- overload or maintenance

A 503 means the server is alive but cannot handle requests right now. This often happens during traffic spikes when the server runs out of capacity, or during deployments when the application is restarting. Some teams intentionally return 503 during maintenance windows.

504 Gateway Timeout -- the slow death

A 504 means a reverse proxy gave up waiting for your application to respond. The application is running but too slow. This often points to a slow database query, a deadlocked thread pool, or an external API dependency that is hanging. If you see 504s from multiple regions simultaneously, the problem is almost certainly on your end rather than a network issue.

How CronAlert uses status codes

When you create a monitor in CronAlert, you set an expected status code -- the code your URL should return when everything is working. CronAlert hits your URL on schedule and compares the actual response code against the expected one. If they do not match, the check is marked as a failure.

This means you can monitor for any status code, not just 200. Some practical examples:

  • Monitor a health endpoint expecting 200
  • Monitor a POST API endpoint expecting 201
  • Monitor a protected page expecting 401 -- if it suddenly returns 200 without authentication, something is wrong with your auth layer
  • Monitor a decommissioned URL expecting 404 -- if it starts returning 200 again, an old deployment may have leaked back into production

The expected status code is not always 200. Set it to whatever your endpoint returns when it is healthy.

Common gotchas

These are the status code scenarios that cause the most confusion in monitoring setups. Each one looks like an outage but usually is not -- or looks normal but hides a real problem.

Redirect chains that create false alarms

You monitor http://example.com. It redirects to https://example.com. That redirects to https://www.example.com. That redirects to https://www.example.com/en/. Your monitor sees a 301 and alerts you.

The fix: always monitor the final destination URL. Check where your URL ends up by following the redirects manually, then use that final URL in your monitor. This also improves check performance since the monitor does not waste time following a chain.

403 from WAF or CDN bot protection

Cloudflare, AWS WAF, Sucuri, and other security layers often block requests that look automated. Monitoring requests -- especially ones without typical browser headers -- get flagged as bots. The monitoring tool reports a 403, but your site is perfectly accessible to real users in real browsers.

Solutions: allowlist your monitoring service's IPs if possible, or check if the monitoring tool can send custom User-Agent headers that match a real browser. In CronAlert, you can add custom headers to any monitor, including a User-Agent header.

429 rate limiting from aggressive check intervals

If you monitor the same endpoint from multiple services or with very short intervals, you might hit rate limits. A 429 response does not mean your site is down -- it means the monitoring requests themselves are being throttled.

If this happens, consider whether you genuinely need 1-minute intervals on that endpoint, or if 3-minute checks would be sufficient. You can also check if your API supports dedicated rate limit tiers for monitoring tokens.

Soft 200 errors -- the silent killers

This is the most dangerous gotcha. Your server returns a 200 OK, so your monitor thinks everything is fine. But the response body is an error page, a "Service temporarily unavailable" message, or a login page because the session expired.

Many web frameworks return 200 for custom error pages. Many CDNs serve cached "sorry" pages with a 200 status. If you only check the status code, you will miss these completely.

The solution is keyword monitoring. Pick a string that should appear in a healthy response -- a specific heading, a JSON key, a unique piece of content -- and configure your monitor to verify it is present. If the keyword is missing, the check fails regardless of the status code. For deeper validation of response structure, content monitoring can catch issues that a single keyword would miss.

Status codes and keyword monitoring -- why 200 is not always "up"

Consider a typical single-page application. The server always returns 200 and an HTML shell, even when the API behind it is broken. The JavaScript loads, makes API calls, and gets errors -- but the initial page load was a 200. Your monitor says "up." Your users see a blank screen.

Or consider a WordPress site where a plugin crashes. WordPress catches the error, renders a "There has been a critical error" page, and returns it with a 200 status code. The site is functionally down, but HTTP says it is fine.

These scenarios are more common than total server crashes. Keyword monitoring catches them by looking beyond the status code at the actual content being served. Here is the strategy:

  • For web pages -- monitor for a string that only appears on the fully rendered, healthy page. A footer copyright line, a specific navigation item, or a unique heading.
  • For APIs -- monitor for a JSON key that should always be present, like "data" or "status":"ok".
  • For health endpoints -- monitor for the full healthy response string, not just a partial match. Check for "status":"ok", not just "status".

Status codes tell you the server responded. Keywords tell you the response was correct. Use both together for monitoring you can actually trust.

What to do when you get specific error codes

When your monitor fires an alert, the status code tells you where to start looking. Here is a practical debugging guide.

Getting 301 or 302

Not an emergency. Update your monitor URL to the redirect destination. If the redirect is new and unexpected, check whether someone changed DNS records, updated the web server configuration, or deployed a URL migration.

Getting 403

First, check if the page loads in a browser. If it does, the issue is likely WAF or CDN bot protection blocking the monitor. If the page is also blocked in a browser, check for permission changes, expired SSL certificates, or IP-based access controls. For sites behind Cloudflare, check the security event log in the Cloudflare dashboard.

Getting 404

Verify the URL is correct in your monitor configuration. If it was working before, check recent deployments for URL changes. Look at your routing configuration. If you recently migrated to a new framework or CMS, routes may have changed without redirects being set up.

Getting 500

Check your application logs. A 500 means an unhandled exception, so there should be a stack trace or error message. Common culprits: database connection failures, missing environment variables after a deploy, null references from unexpected data, or dependency updates that introduced breaking changes.

Getting 502

Check if your application process is running. On a typical setup with Nginx in front of a Node.js or Python app, a 502 means Nginx cannot reach the app. Run systemctl status your-app or check your process manager. If you are on a PaaS (Heroku, Render, Railway), check their status page -- the platform itself might be having issues.

Getting 503

Check server load (CPU, memory, connections). A 503 often means the server is overwhelmed. If it coincides with a traffic spike, you need to scale up. If it happens during deployments, your deployment process might need zero-downtime configuration. Some applications return 503 intentionally during startup -- wait a minute and check again.

Getting 504

The application is alive but too slow. Check for slow database queries, external API calls that are hanging, or thread pool exhaustion. Look at your reverse proxy's timeout configuration -- you may need to increase it, but more importantly, figure out why the application is slow. A 504 is a symptom, not the root cause. If you are seeing SSL-related timeouts, certificate issues can also cause gateway timeouts during the TLS handshake.

Getting connection refused or timeout (no status code)

If your monitor cannot connect at all, there is no HTTP status code -- just a connection error. This means the server is not listening on that port, the DNS is not resolving, or a network-level firewall is blocking the connection entirely. This is usually more serious than any HTTP error because it means the server is truly unreachable.

FAQ

Is a 301 redirect a sign of downtime?

Not necessarily. A 301 means the URL has permanently moved to a new location. If your monitor is pointed at the old URL, it will report a 301 instead of 200. This is not downtime -- it means you need to update your monitor to use the new URL. However, redirect chains (multiple 301s in sequence) can cause timeouts and should be investigated. Always monitor the final destination URL to avoid false alarms.

What is the difference between a 502 and a 503 error?

A 502 Bad Gateway means a reverse proxy or load balancer received an invalid response from an upstream server -- typically because the application process crashed or is not running. A 503 Service Unavailable means the server is temporarily unable to handle requests, often due to overload or scheduled maintenance. Both indicate downtime, but 502 usually points to a crashed process while 503 suggests capacity issues. The debugging approach is different: for 502, check if the app is running; for 503, check server load and scaling.

Should I alert on 429 Too Many Requests?

It depends on why you are getting rate limited. If your monitoring tool is hitting a rate limit, reduce your check frequency or use a dedicated monitoring token with higher rate limits. If your actual users are hitting 429 errors, that indicates a capacity problem worth alerting on. For uptime monitors, a 429 from your own endpoint usually means your check interval is too aggressive or you are monitoring the same URL from multiple services simultaneously.

Can a page return a 200 status code but still be down?

Yes, and it happens more often than you might think. This is called a "soft 200" or "false 200." The server returns a 200 OK status code, but the response body contains an error message, a maintenance page, or missing content. CDNs serving cached error pages and frameworks rendering custom error templates both commonly do this. Keyword monitoring catches these silent failures by checking the actual response body for expected content, not just the status code.

What HTTP status code should I set as the expected code in my monitor?

Set it to whatever your endpoint returns when it is working correctly. For most web pages and health checks, that is 200. For REST APIs that create resources via POST, it might be 201. For DELETE endpoints, it could be 204. If you are monitoring a protected endpoint without sending credentials, you might expect a 401 or 403 -- and that is a valid configuration. The key is matching the actual healthy response. Visit your URL in a browser or with curl -I and note the status code it returns -- that is your expected code.

Create a free CronAlert account to start monitoring your URLs with status code validation and keyword monitoring. The free plan includes 25 monitors with email, Slack, Discord, and webhook alerts -- enough to cover every critical page and API endpoint.