If your system logs "answered 0" when a service times out, you are lying to your dashboard. A recent post from minia2a details a critical operational failure where five services in a review queue were flagged with a status code of 0. The probe gave up after ten seconds, and the string 0 originated from the local socket layer, not the remote server. Yet, the human-readable log claimed the service had replied. This is a classic dev-tools trap: treating the absence of a response as a response of zero.

The Anatomy of a Silent Failure

The bug lived in a classifier that handled specific HTTP status codes like 402, 400, and 403. When the probe failed to get a response, the exception handler returned a status of 0 and stuffed the error text into the body. This sentinel value then fell into a catch-all branch that formatted the log line as "unpaid call answered %d". The result was a misleading narrative. The verdict was HOLD, which is safe, but the reason was wrong. A reviewer reading "answered 0" assumes the remote end is broken, not that the local measurement failed. This distinction is vital for debugging infrastructure issues.

Three Shapes of the Same Mistake

This pattern repeats in three distinct forms. First, the transport gap: a timeout or DNS failure prints a status code. Second, the "answered, no value" trap: a JSON-RPC node returns {"result": null}, but the code prints balance: 0. This tells the caller the account is empty, not that the data is unknown. Third, the non-2xx parser: a shared helper parses a 502 error page into an empty object {}. Downstream handlers then report a confident empty result. In every case, the code defaults to a plausible value when it should signal uncertainty. The fix is refusing to have a default. Propagate "no value" as its own outcome so the caller can retry or fail loudly.

Implementing Measurement Gaps

The solution is a dedicated branch for status 0 before the catch-all. The verdict stays HOLD, but the reason changes to "no response from the endpoint... this is a measurement gap, not a reading about the gate". Five new controls were added to pin this wording. They assert that the reason never contains "answered 0", always carries the transport error, and explicitly uses the phrase "measurement gap". The selftest suite grew from 41 to 178 controls, all fixture-driven without network dependencies. This ensures that the code distinguishes between "I did not find out" and "I found out it is nothing".

Key Takeaways

  • A timeout is not a status code; it is a lack of data. Treat it as such.
  • Never use 0, null, {}, or [] as a default for failed measurements if they are valid successful responses.
  • Log lines must reflect the source of the data: local measurement failure vs. remote server response.
  • Build fixture-driven tests that simulate transport gaps to prevent regression of this specific error class.

The Bottom Line

Your logs are your source of truth. If they conflate silence with zero, you are building on quicksand. Stop guessing and start measuring what you actually know.