Curious Pandas

A 200 can still be broken

Exit codes and status codes say a request completed, not that it worked. Watch three health checks get fooled, and learn to assert on what came back.

13 min+35 XP for finishing

Here’s a health check that ships every day, all over the world:

curl https://shop.bamboo.example/ && echo "site is up"

It prints “site is up” when the site returns 500 Internal Server Error. By default, curl doesn’t treat an HTTP error status as a failure. It got an answer, so it exits 0. The manual says so in as many words. You have to add --fail to get exit code 22 on a 4xx or 5xx.

So you fix the check to look at the status code. Now it catches the 500, and it waves through something worse: a 200 OK whose page is an empty shell. Modern sites send a skeleton page and a script that fills it in. If that script fails, or the data request behind it fails, the server still says 200, and the visitor sees a blank screen.

Three checks, ten ways to fail

Try each failure and watch the scoreboard. A check is fooled when it says “fine” about a broken site, or “broken” about a fine one.

Would your health check notice?real curl output
    $ curl -v https://shop.bamboo.example/

    Only one check is right every time: does the body contain something that only a working page would contain? Not “is the body non-empty”: the empty shell isn’t empty. Look for the shop’s name, a product, a value you know should be there. For a page that builds itself in the browser, the honest version is to render it in a real browser and read what’s on screen, which is exactly how this site checks its own pages.

    Check yourself+10 XP

    Your monitoring runs `curl -s https://api.example/health` and alerts if the exit code isn't 0. The API starts returning 503 Service Unavailable. What happens?

    401 vs. connection reset

    Two failures look the same in a test log: “request failed”. They mean opposite things.

    • A 401 is an answer from the application. Your request crossed the network, got through TLS, reached the code, was read, and was refused for lack of credentials. Whatever is guarding that door is working.
    • A connection reset (curl exit 56) means something on the path tore the connection down. The application may never have seen your request. If you were testing that a firewall blocks you, a reset might be the firewall doing its job. If you were testing the application’s own login check, the reset proves nothing about it.

    When you test that something is refused, check how it was refused. “It failed” isn’t evidence. “It failed at the layer I meant to test” is.

    Check yourself+10 XP

    You expect an internal admin API to be unreachable from the internet. Your test calls it and gets 401 Unauthorized. Did the boundary hold?

    Check yourself+10 XP

    Which check would catch the empty-shell page?

    Do it for real · your machine+50 XP bonus

    Everything above ran in your browser. Now do it on a real cluster with tilt lab 08-empty-dashboard (profile observability). You need Docker, kind and Tilt, about 15 GB of free disk and 8 GB of spare RAM. Setup guide · Can my machine run it?

    Make curl lie, then make it honest:

    curl -s -o /dev/null -w "%{http_code}\n" https://hello.localhost/nope ; echo "exit=$?"
    curl -sf -o /dev/null https://hello.localhost/nope ; echo "exit=$?"
    curl -s https://hello.localhost/ | grep -q "Hello from the platform" && echo "really up"

    The hello app is podinfo. Its message, “Hello from the platform”, is set in examples/hello-world/deployment.yaml, so that string is something only a working page contains.

    The platform’s own ./scripts/platform.sh check does it properly: it renders every service in a real browser and reads the screen.

    Self-reported. We can't see your machine, and we don't want to. This is a bonus, never required.

    Sources

    Finished reading?

    Missions and quizzes above earn their own XP. This marks the lesson done.