Kcalbin LLC

HTTP 200 Does Not Mean Your Data Source Works

The worst kind of broken pipeline is the one that reports success. Here are the specific shapes that takes, and how to actually test for them.

27 September 2026 · Kcalbin LLC · Every example below was observed on our own systems.

The shape of the problem

A monitoring check that asks "did the request succeed" is asking a question the failure mode does not answer. Sources fail in ways that produce a perfectly healthy-looking response:

- The feed URL now serves a marketing page at the same address. - The endpoint redirects to a bot wall that returns 200. - The API returns a valid envelope with an empty array because your key silently lost a permission. - The page returns 200 and the content you wanted is rendered client-side, so it is not in the body.

In every case: status 200, no exception, nothing in the error log, and a dashboard that is green.

Four real examples

A feed that became a webpage. We had two sources recorded as `status=healthy` with `http=200`. Fetching them directly returned `<!DOCTYPE html>` — a rendered site, not a feed. The health check recorded the status code and never asked whether the body was a feed.

A redirect to a bot wall. A Federal Register RSS endpoint answered `302`, and following it landed on an "unblock" challenge page returning 200. Anything measuring the final status saw success. The same organisation's JSON API served the identical documents without complaint — the data was never gone, only the door had moved.

An entitlement failure that looks like no data. A lookup API began returning well-formed responses with nothing in them. It read as "no matches found" for weeks. The account had lost access to that lookup type, which is a 403 wearing an empty-result costume.

A function whose exception was swallowed. A call wrapped in `catch (_) {}` threw on every invocation because the function it named did not exist. The caller recorded "no results" and moved on, indistinguishable from a genuine empty answer.

What to check instead of the status code

Check the shape, not the code. For a feed, parse it and count items. Zero items from a source that had forty yesterday is a failure regardless of status. For JSON, assert on a field you actually need.

Check the magic bytes. If you expect XML and the first bytes are `<!DOCTYPE html`, you have your answer without parsing anything.

Ask a question with a known answer. The strongest probe is one that must return results. If you query something guaranteed to match and get nothing, the transport failed — you do not have to distinguish between down, rate-limited and unauthorised to know it is broken.

Make "broken" and "empty" log differently. This is the cheapest high-value change available. A bare `catch` that swallows an exception and returns an empty list makes a wiring bug indistinguishable from a quiet day, possibly for weeks. Log the exception, even if you still degrade gracefully.

Alert on absence, not just on errors. A source that has produced nothing for three days is a stronger signal than a source that produced one error.

The deeper version: does the consumer actually work?

A probe that confirms an API answers does not confirm that your code can use it. Those are different claims and only one of them is usually tested.

A health check can be green because the endpoint is reachable, while every real call from your pipeline fails on an entirely separate fault. If it is worth monitoring, monitor the path your production code takes — not a simplified version of it that shares only the hostname.

The rule that generalises

Silence is not evidence of quiet. Absence of error is not evidence of success, and a health check that cannot fail is not a health check.

If a source has gone quiet, make your system say which of these it is: nothing happened, or *I could not find out*. They demand opposite responses, and any monitoring that collapses them will eventually collapse them at the worst possible moment.