Step 1 of 5 · Reading · ~4 min
Read
Production Features
Errors & Status Code Semantics
A status code is a promise about whose fault a failure is and what the client should do next. Pick the wrong one and you break behaviour you cannot see: retry logic, caches, alerts, crawlers. Your program will now read a whole raw request and answer with the one status it deserves, in the right order.
The families
| Code | Meaning | What the client may do |
|---|---|---|
| 400 | malformed request | fix the request |
| 401 | no valid credentials; must send WWW-Authenticate | authenticate, then retry |
| 403 | credentials understood, not allowed | stop |
| 404 | nothing here | give up or look elsewhere |
| 405 | path exists, verb does not; must send Allow | use a listed verb |
| 408 | the request never finished arriving | retry on a new connection |
| 411 | a body is expected but its length is not declared | add Content-Length |
| 413 | body larger than the server accepts | send less |
| 414 | target longer than the server accepts | shorten it |
| 415 | body is in a media type the endpoint cannot read | change Content-Type |
| 431 | header block too large (count or size) | send fewer or smaller headers |
| 500 | the handler failed | nothing: it is the server's problem |
| 501 | method or feature not implemented | do not retry |
| 503 | overloaded or in maintenance; Retry-After says when | retry later |
| 505 | HTTP version not supported | use 1.0 or 1.1 |
The 4xx/5xx boundary is blame assignment with operational weight: 5xx pages the on-call engineer, 4xx does not. A malformed body is a 400, not a 500. Miscoding it wakes the wrong person at 3 a.m. The 401/403 pair is the other classic: 401 means "I do not know who you are", 403 means "I know, and the answer is no".
Precedence is part of the spec
A request can be wrong in several ways at once, and a server must report one. The order is not arbitrary: each stage can only run if the earlier ones succeeded.
- The request line. Shape first (three fields, an uppercase method, a target starting with
/, a version likeHTTP/1.1):400. Then the target length:414. Then an unknown method:501. Then an unsupported version:505. - The header block. Read line by line. A line over the size limit is
431; a line with no colon, with leading whitespace, or with an empty or spaced name is400; more headers than the limit is431. If the input ends before the empty line, the client never finished:408. For HTTP/1.1,Hostmust appear exactly once or the answer is400. - Message framing.
Transfer-Encodingis not supported here:501. AContent-Lengththat is not digits, or two that differ, is400. A declared length over the body limit is413before any body is read, which is the whole point of declaring it. A POST with no length at all is411. Fewer body bytes than declared:408. Framing errors outrank routing errors because the server cannot even consume the request without a clear frame. - Routing. Cut the query string. An unknown path is
404, a known path with the wrong verb is405withAllow. - Endpoint rules.
POST /api/itemsneedsContent-Type: application/json(the part before any;, case-insensitive) or it is415, and a non-empty body or it is400./adminneedsAuthorization: Bearer admin-token: missing is401with aWWW-Authenticateheader, anything else is403.GET /crashsimulates a handler failure:500.GET /maintenanceis503withRetry-After.
The limits, and the routes
The limits here are tiny so that fixtures stay readable (real servers use around 8 KB): target at most 40 bytes, line at most 80 bytes, at most 8 headers, body at most 16 bytes. The routes: GET/HEAD on /, /admin, /crash, /maintenance, and GET/HEAD/POST on /api/items.
The contract
Print the status line as <code> <reason>, then any required header, one per line: Allow: GET, HEAD (methods sorted), WWW-Authenticate: Bearer realm="admin", Retry-After: 120. Reason phrases are in the starter. Success is 200 OK, or 201 Created for the POST.
Common mistakes
- Using 500 as the default for client mistakes.
- Checking the route before the framing, so a huge POST to a missing path gets 404 instead of 413.
- Answering 403 when no credentials were sent.
Your exercise
The starter reads one request and has the status table. You decide, in order, which status it deserves.
Discussion
Ask a question, share an insight, or help someone who’s stuck.
Sign in to post a comment or reply.
Loading…