HTTP 418 is I'm a teapot, a joke that outlived the joke. RFC 2324, the Hyper Text Coffee Pot Control Protocol, published on April 1, 1998, says that “any attempt to brew coffee with a teapot should result in the error code 418 I’m a teapot”, adding that the response body may be “short and stout”. HTCPCP is a parody of HTTP, with a BREW method and an Accept-Additions header for milk and syrup. RFC 7168 extended it to tea in 2014.
What HTTP says about it now
RFC 9110 section 15.5.19 is titled “418 (Unused)”. The joke was deployed often enough that the number can’t be given a real meaning, so it’s reserved in the IANA registry and may be reassigned only if the 4xx codes ever run out. Nothing else about it is standard: no headers go with it, and it isn’t heuristically cacheable. A client that doesn’t know 418 treats it as a plain 400, as RFC 9110 requires for any unrecognized 4xx.
Spelling in libraries
RFC 2324 writes it I'm a teapot, with a lowercase t, and so does the card below. Libraries vary:
Go http.StatusText(418) I'm a teapot
Node.js http.STATUS_CODES[418] I'm a Teapot
Python HTTPStatus.IM_A_TEAPOT I'm a Teapot (Python 3.9 and later)
It hardly matters on the wire. HTTP/2 and HTTP/3 don’t send a reason phrase at all, and RFC 9112 tells HTTP/1.1 clients to ignore it, so code that checks for 418 should compare the number.
Where it belongs
Easter eggs, prank endpoints, and tests of how a client copes with a status code it has never seen. In a real API, 418 gives the client nothing to act on, and anyone reading your logs has to guess what it meant. Use the code that says what happened:
refusing this caller 403 Forbidden
slow down 429 Too Many Requests
can't serve right now 503 Service Unavailable
not implemented 501 Not Implemented
In your stack
app.get('/coffee', (req, res) => res.status(418).send("I'm a teapot")); // Express
return "I'm a teapot", 418 # Flask
raise HTTPException(status_code=HTTPStatus.IM_A_TEAPOT) # FastAPI
http.Error(w, http.StatusText(http.StatusTeapot), http.StatusTeapot)
return ResponseEntity.status(HttpStatus.I_AM_A_TEAPOT).build(); // Spring
Searching teapot in the tool below finds it by its phrase. Its card is marked Reserved · RFC 9110 rather than unofficial, because the registry does list the number.