False Positives (Down But Not Really)
Your site loads fine in your browser and DownBad says it is down. One of you is wrong, and it is worth five minutes to find out which. A monitor you have learned to ignore is worse than no monitor at all.
This is also where every URL, ping, and port monitor sends you when nothing more specific fits, so not every failure that lands here is false. Some of them are the check being right about a host that is genuinely unreachable. The error category recorded on the incident is what separates the two, and the table in step 1 sorts them — including which categories your kind of monitor can even produce, because URL, ping, and port checks each report a different set.
Symptom
Section titled “Symptom”An incident is open — you may have been paged for it — but the page loads normally when you check it yourself. Uptime looks worse than your own logs say it should, and the failures cluster around one monitor rather than everything you run.
Or you followed the troubleshooting link from a failing URL, ping, or port
monitor and do not yet know whether the failure is real. The starting point is
the same either way: read the error category, then work only its branch.
status_code and timeout are where false positives mostly live.
host_unreachable, network_unreachable, and not_found almost never are —
those are an outage, a wrong port, or a wrong address, and the fastest thing you
can do is stop looking for a phantom.
Likely causes
Section titled “Likely causes”These are the reasons an alert can be wrong. When the alert turns out to be right, the cause is named in the branch for your category below.
- Your CDN or WAF blocked the check. This is the most common cause by a wide margin. Cloudflare Bot Fight Mode, AWS WAF rate rules, and country-blocking all return a challenge or a 403 to an automated client while leaving your browser alone.
- Rate limiting. A monitor on a 60-second interval plus a strict per-IP limit will eventually trip it, especially on an endpoint that is also getting real traffic.
- Your browser is cheating. It has a warm TCP connection, a cached DNS answer, and a session cookie. Every DownBad check starts cold.
- The check is stricter than your eyes. An expected status code, a required body string, or a timeout set below your real response time will fail a page that renders fine.
- ICMP is filtered, not down. Plenty of hosts, cloud firewalls, and security groups drop ping while serving traffic perfectly. A ping monitor on such a host fails forever and tells you nothing; a port monitor on the port you actually serve tells you the truth.
- The port is open to you and not to us. A security group or firewall allowlist that includes your office and not the public internet makes a port check fail while everything works from your desk.
- A genuinely intermittent failure. One request in twenty fails, and you happened to reload during a good one. This is a real outage; it is just a small one.
- You only had one vantage point. Your reload came from one network path. DownBad re-checks a failure from up to three AWS regions on every plan and the majority decides, so the check’s verdict already rests on more vantage points than yours.
Fix steps
Section titled “Fix steps”-
Read the check output on the incident before you do anything else. It records one error category, and which categories are possible depends on the kind of monitor. Find yours below; the branch it names is the only one you need to read.
Category Reported by What it means Branch status_codeURL A response arrived, carrying a code the monitor does not accept Step 3 timeoutURL, port Nothing answered inside the time limit Step 4 dnsURL The hostname did not resolve Step 5 not_foundPort The hostname did not resolve Step 5 sslURL The TLS handshake failed, so no request completed Step 6 connection_refusedURL, port Something answered, and what it said was “no” Step 7 host_unreachablePort The network was reached; the host was not Step 8 network_unreachablePort There was no route to the network at all Step 8 blocked_targetURL We refused to check the address; nothing was fetched Step 9 permission_deniedPing Our checker could not start the ping program — this one is ours Step 10 unknownURL, ping, port The failure matched none of the above Step 11 A ping monitor reports none of the network categories above. A ping that runs reports the share of packets that came back, whatever the reason for a loss. Everything else is
permission_deniedorunknown, and the message beside it says which of two very different things happened: one of ours, where the ping program could not be started at all, or one of yours, where it ran and printed nothing to read — which is what a name that does not resolve produces. Step 10 and step 11 tell them apart. -
Reproduce it from a cold path. Your browser cannot do this; these can. Use the one that matches your monitor:
Terminal window # URL monitorcurl -sS -o /dev/null -w '%{http_code} %{time_total}s\n' https://example.com# Ping monitorping -c 20 example.com# Port monitornc -vz example.com 443Run it a dozen times. If it fails once, the monitor is right and you have an intermittent fault, not a false positive.
-
status_code— compare the code the check recorded with the code the monitor expects. A 403 or a 503 that your browser never sees is your WAF or CDN challenging an automated client. Allowlist the checker rather than loosening the monitor: DownBad identifies itself in its User-Agent (DownBad/1.0 (Uptime Monitor; ...)) unless you have chosen a different preset on the monitor. -
timeout— the request did not fail, it ran out of time. On a URL monitor your browser would have shown a slow page, not an error. On a port monitor it means the TCP handshake got no reply in time, which on a host that drops packets to closed ports looks exactly like being down — check step 8 before you page anyone. A ping that gets no reply in time is not reported this way: it is a measured loss, and the percentage is in the result. For the slow case, go to Slow Response Times. -
dns(URL) ornot_found(port) — two spellings of the same failure: the hostname did not resolve from our checker, even though it resolves from yours, so nothing was ever connected to. Check the monitor’s hostname for a typo first — it costs ten seconds — then go to DNS Records Changed Unexpectedly, which covers resolution failures as well as record changes. -
ssl— the TLS handshake failed, so no HTTP request was ever completed. An expired certificate, a hostname it was not issued for, or a chain missing its intermediate — which your browser repairs from its own cache and our checker will not. Go to SSL Certificate Expiring; its first step prints exactly what your server is serving, which is usually not what is on disk. -
connection_refused— something answered, and what it said was “no”. That is a firewall rule or a service that is not listening, not a false positive. On a port monitor, confirm the port in the error message is the one your service actually listens on, then check it is open from outside your own network rather than only from a machine inside it. -
host_unreachable,network_unreachable— the packets did not get to the host, and neither of these is usually a false positive.host_unreachablemeans the network was reached and the host was not, so it is down or it no longer has that address.network_unreachablemeans there was no route to the network at all, which most often means the monitor holds an address that moved during a migration. Confirm the address on the monitor is still the host’s address, then try step 2 from a network other than your office before assuming the fault is on our side. -
blocked_target— DownBad refused to run the check because the target resolves to a private or internal address. Nothing was fetched. Point the monitor at an address the public internet can reach. -
permission_denied— this one is ours, not yours. It means our checker could not start the ping program at all: the binary is missing from the runtime, or it is there and may not be executed. The ping never left our side, nothing about your host was tested, and no firewall, route, or security group of yours produced it. There is nothing to fix in your infrastructure: re-run the check, and if a ping monitor keeps recording it, tell us. A ping monitor whose message begins “Ping did not run” is the same story with a different cause — a platform the ping library refuses — and is equally ours. -
unknown— the failure did not match any category, so the error message beside it is the real information. Read that first, then reproduce it with the matching command in step 2. On a ping monitor the commonest one is “Ping produced no statistics”: the ping program ran and exited without a summary line, so there was no reply and no loss figure to read. A host name that does not resolve does exactly that, and so does a checker that is refused the raw socket ICMP needs — the message cannot tell you which, so confirm the name resolves from your own machine before assuming the fault is ours. If it reproduces, the monitor is right and the message names the fault; if it never reproduces, treat it as a transient blip and go to step 12. -
Still cannot reproduce it? Raise the consecutive-failure threshold on the monitor’s notification profile to 2 or 3 so a single blip does not open an incident. Multi-region verification is already on for every plan; on a paid plan you can also choose which regions do the re-check.
Prevention
Section titled “Prevention”- Allowlist the checker in your WAF and CDN. Do this once, properly, instead of tuning thresholds until the alerts stop.
- Set thresholds from measurement. Two consecutive failures is a sensible default for most things; one is right only where a single failed request costs you money.
- Set timeouts above your real p95, not at a round number you liked.
- Do not monitor an endpoint that rate-limits. Give the checker a cheap, unrated health endpoint that exercises the parts you care about.
- Do not use a ping monitor on a host that filters ICMP. Monitor a port it actually serves instead — a check that cannot succeed is not a monitor, it is a recurring alarm.
- Keep ping and port monitors pointed at current addresses. An IP that moved
during a migration keeps failing indefinitely while the host it names is fine:
host_unreachableornetwork_unreachableon a port monitor, and on a ping monitor either total packet loss or no figure at all, depending on whether the old address still routes. - Check that the monitor’s expectations still match reality after any deploy that changes status codes, redirects, or response bodies.