Crux Read real HTTP headers, a curl trace, and a gRPC exchange; predict the behaviour and pick the highest-leverage fix a senior engineer would make first.
Your altitude — climbing toward senior
ZeroJuniorMiddleSenior
You are at senior altitude — in orbit
◷ 14 min
Wire dumps and response headers are where HTTP problems are actually diagnosed. Read the exchange, predict what the browser, CDN, or QUIC stack will do, then choose the fix a senior engineer reaches for first.
Goal
Practise the loop you run in every HTTP incident: read the headers and the trace, predict the protocol-level behaviour, and reach for the structural fix before tuning anything.
The server advertises h3 via Alt-Svc but the HTTP/3 handshake fails. What is wrong, and what is the first fix?
Heads-up QUIC uses the same TLS cert as the TCP listener on 443; there is no separate QUIC port to cover. The x-quic-version: draft-29 header shows the real cause — an obsolete QUIC draft.
Heads-up max-age only controls how long the client remembers the h3 hint; it cannot cause a handshake protocol violation. The draft-29 implementation is the defect.
Heads-up HTTP/2 already worked in the first call. The explicit 'protocol violation: invalid initial packet' is a real QUIC-version mismatch, not a curl flag issue.
Snippet 2 — the cached user profile
GET /api/user/profile HTTP/2authorization: Bearer eyJ...userAHTTP/2 200 OKcontent-type: application/jsoncache-control: max-age=300{"id":"userA","email":"a@example.com"}
Quiz
Completed
Users report seeing each other's profiles intermittently. Reading only these headers, what is the bug and the correct fix?
Heads-up HTTP/2 streams never cross request bodies between connections or users. The leak is a caching-semantics bug: a per-user response marked publicly cacheable.
Heads-up Tokens belong in the Authorization header precisely because URLs leak via Referer and access logs. The bug is the missing private/Vary on the response, not the token's location.
Heads-up A short TTL does not mix users; any TTL on a publicly-cacheable per-user response leaks. The fix is scoping the cache (private/no-store), not changing max-age.
Snippet 3 — the gRPC response
HTTP/2 200 OKcontent-type: application/grpc(DATA frames: serialized protobuf message)(trailing HEADERS frame)grpc-status: 5grpc-message: user not found
Quiz
Completed
The HTTP status is 200 but grpc-status is 5 (NOT_FOUND). Why is the result in a trailer, and what breaks if a browser calls this directly?
Heads-up By design gRPC keeps HTTP status at 200 and signals the RPC outcome in grpc-status trailers; this is correct, not a bug. The trailer placement reflects end-of-stream timing.
Heads-up Trailers are about end-of-stream metadata timing, not CORS. Browsers simply don't expose HTTP trailers to JS, hence gRPC-Web.
Heads-up HTTP/2 supports trailing HEADERS frames, and gRPC relies on them. The body holds the protobuf message; the status legitimately lands in the trailer.
Both requests arrive at once over HTTP/3. Reading the RFC 9218 Priority headers, which does the server send first, and what is the rule?
Heads-up RFC 9218 inverts that intuition: lower u is more urgent. u=1 (CSS) outranks u=5 (image), so the CSS is sent first.
Heads-up That was the failure mode RFC 9218 fixed. With Priority headers honoured by modern servers and CDNs, the server reorders DATA frames by urgency.
Heads-up Multiplexing allows interleaving, but priorities tell the server how to weight DATA-frame bandwidth — favouring the lower-urgency-value (more urgent) stream.
Recap
Every HTTP incident is read in headers and traces: an Alt-Svc h3 hint backed by a draft-QUIC stack wastes an RTT per client; a per-user response missing private/no-store and Vary leaks across a shared cache; gRPC’s real outcome lives in a trailing HEADERS frame (200 at the HTTP level) and needs gRPC-Web for browsers; and RFC 9218 urgency is inverted — lower u is more urgent. Read the wire, predict the protocol behaviour, then apply the structural fix.