Course outline · 0% complete

0/25 lessons0%

Course overview →

Capstone: run the diagnosis

lesson 9-2 · ~13 min · 25/25

On call, end to end

This capstone puts the whole course together: first the checklist's decision logic as a script, then three real-style tickets diagnosed from their symptoms alone.

The script takes three findings, in checklist order: the DNS result (ok/fail), the TCP result (ok/fail), and the HTTP status code. It reports the first failing layer with advice, following the rules you know:

  • DNS failed → check the name and the resolver (unit 2)
  • TCP failed → server down or port blocked (unit 3, lesson 9-1)
  • status ≥ 500 → server-side (lesson 4-3)
  • status ≥ 400 → client-side, fix the request
  • otherwise → healthy

The checklist as a script

The diagnose function is the whole checklist encoded as one if/elif chain: DNS first, then TCP, then the status code ranges.

diagnose() {
  dns=$1; tcp=$2; http=$3
  if [ "$dns" = "fail" ]; then
    echo "DNS failure: check the domain name and your resolver"
  elif [ "$tcp" = "fail" ]; then
    echo "TCP failure: server down or port blocked, check host and firewall"
  elif [ "$http" -ge 500 ]; then
    echo "HTTP $http: server-side bug, check server logs"
  elif [ "$http" -ge 400 ]; then
    echo "HTTP $http: client-side problem, fix the request"
  else
    echo "HTTP $http: all good"
  fi
}

diagnose fail - -
diagnose ok fail -
diagnose ok ok 503
diagnose ok ok 404
diagnose ok ok 200

Output

DNS failure: check the domain name and your resolver
TCP failure: server down or port blocked, check host and firewall
HTTP 503: server-side bug, check server logs
HTTP 404: client-side problem, fix the request
HTTP 200: all good

Reading the chain

  • The order is the important part, not the syntax. Each layer depends on the one below it, so the first failure found is the one worth reporting.
  • A name that never resolved makes the TCP result meaningless, and a connection that was refused makes the status code meaningless. That is why the first two calls pass - for the layers that were never reached.
  • Bash compares strings with = and numbers with -ge, and mixing them up is a classic source of silent wrong answers rather than loud errors.
  • The 500 check must come before the 400 check, since 503 is also greater than or equal to 400 and would match the wrong branch. An elif chain is ordered, so overlapping ranges have to run from narrowest to widest.
  • Reporting the lowest broken layer and stopping there is exactly what an engineer does on call. The script is a written form of a habit.

Ticket 1: could not resolve host

The failing layer is DNS.

The name never became an IP address, so nothing else was even attempted. No packet was ever sent to the server, which means the server's health is entirely unknown at this point.

"Resolve" is the giveaway word in the error text, and curl error 6 is specifically the resolution failure.

The next moves come from unit 2: check the spelling, try dig +short on it, and try a known-good name such as example.com to learn whether the resolver itself is broken or only this one domain is.

Internal names like api.internal-shop.com often resolve only on the company network or over a VPN, which makes "works for my teammate" a strong hint rather than a contradiction.

Ticket 2: connection refused on port 5432

The failing layer is TCP.

DNS worked, since dig answered, and the machine is up, since ping answered. The connection attempt then reached the machine and was actively refused, which means nothing is listening on port 5432, or a firewall rejected it with a reply.

Port 5432 is PostgreSQL from lesson 2-2, so the likely truth is that the database process is not running, or it is listening on a different port or a different interface.

The instant refusal, in contrast with a long timeout, is what tells you the machine itself is fine. Refused means the machine replied to say no program is listening there, which is a useful answer rather than a silence.

The interface case is worth knowing: a database bound only to 127.0.0.1 refuses connections from other machines while working perfectly from its own, which looks identical from outside to a stopped service.

Ticket 3: 502 Bad Gateway

The fix belongs on the server side.

502 means a server in the chain, often a load balancer or reverse proxy, asked the application behind it for the page and got garbage or no answer. The first digit 5 settles the question of blame.

Your request was fine and the network was fine, since DNS, TCP, and TLS all succeeded. The failure lives in the site's own infrastructure, one hop past the machine you connected to.

As the client, your only real move is to retry later or report it, and now you can report it precisely: layers 1 through 4 healthy, layer 5 failing with 502.

That precision is the point of the checklist. "The site is down" starts a guessing game, while "TLS completes and the gateway returns 502" tells whoever owns the service where to look.

The certificate warning on one network only

The office network is intercepting TLS. A middlebox presents its own certificate, and the browser correctly refuses to vouch for it.

Same site, two networks, and it fails only where a filtering appliance sits in the middle. That appliance terminates your TLS connection and re-signs traffic with its own certificate, which is exactly the impostor scenario from lesson 7-2.

The chain of trust is doing its job by warning you. The appliance's certificate is not signed by any CA in your browser's root store, so the identity check fails even though the encryption works.

Mobile data bypasses the middlebox entirely, which is why it works there. Comparing two paths is what isolated the variable.

Managed company laptops usually have the appliance's root certificate installed deliberately, which is why the warning appears on a personal device and not on a work-issued one. The interception is the same, and only the trust decision differs.

That comparison used the whole course. You checked layers across two paths and pinpointed the exact one that differs, which is the habit every lesson here was building toward.