Field noteTechnical Foundations7 min read

418 I'm a teapot: the HTTP status code that refuses to brew coffee, and why it will never be deleted

Where HTTP 418 came from (an April Fools RFC in 1998), how a fifteen-year-old saved it from deletion in 2017, why RFC 9110 now reserves it forever, the other status codes with a sense of humour, and why laurelinlabs.com/coffee refuses to brew.

Answer first

HTTP 418 I'm a teapot is the status code a server returns when asked to brew coffee and it is, permanently, a teapot. It was defined on 1 April 1998 in RFC 2324, the Hyper Text Coffee Pot Control Protocol, an April Fools document by Larry Masinter, extended to tea by RFC 7168 in 2014, and nearly removed from Node.js, Go and Python in August 2017 until a fifteen-year-old's save418.com campaign persuaded the HTTP working group chair to reserve it instead. RFC 9110 now lists 418 as unused so it can never mean anything serious. This site returns it at /coffee.

What does HTTP 418 actually mean?

Every HTTP response starts with a three-digit status code: 200 means here you are, 301 means it moved, 404 means there is nothing here, 500 means the server fell over. The 4xx block is for client errors, things the requester did wrong. And in the middle of that block, between 417 Expectation Failed and 421 Misdirected Request, sits 418 I’m a teapot, whose entire specification is that the server refuses to brew coffee because it is, permanently, a teapot. MDN adds the one refinement that makes it a proper spec: A combined coffee/tea pot that is temporarily out of coffee should instead return 503.

Where did the teapot come from?

On 1 April 1998 the IETF published RFC 2324, the Hyper Text Coffee Pot Control Protocol (HTCPCP/1.0), written by Larry Masinter, then at Xerox PARC. It is a complete, deadpan protocol for controlling coffee pots over the web: a coffee: URI scheme, a BREW method (with POST permitted as a fallback), an Accept-Additions header for milk, syrup and sweetener, and error handling for the case where the pot you are addressing is not a coffee pot at all. That case is 418. The document was an April Fools RFC, a tradition the IETF has kept since 1978, but it was also a quiet argument about the fashion for pushing HTTP into every device, made in the only way engineers reliably listen to.

Sixteen years later, on 1 April 2014, RFC 7168 extended the protocol to tea (HTCPCP-TEA), adding an Alternates header for listing available teas and the observation that pots which are teapots should say so with 418. The joke had acquired an errata process.

How was 418 nearly deleted, and who saved it?

By 2017 the code had leaked out of the joke and into real software. Node.js, Go’s standard library, Python’s Requests and Microsoft’s ASP.NET all shipped 418 in their status tables, and a scattering of production servers used it for requests they did not want to dignify with a real error. In August 2017 Mark Nottingham, chair of the IETF working group that maintains HTTP, opened issues asking those projects to remove it, on the entirely reasonable grounds that 418 had never been part of the HTTP standard and the number might one day be needed.

The response came from Shane Brunswick, a fifteen-year-old developer about to start his sophomore year of high school, who put up save418.com with the line that carried the campaign:

It’s a reminder that the underlying processes of computers are still made by humans. It’d be a real shame to see 418 go.

The projects kept the code. Nottingham and Brunswick reached an agreement, and Nottingham himself filed the proposal to reserve 418 formally so the question could never come up again, closing the thread with If you ask me, it’s a tempest in a ... ah, never mind.

Why can 418 never mean anything serious now?

The current HTTP semantics specification, RFC 9110 (June 2022), lists 418 under the heading “418 (Unused)” and reserves it precisely because it was so widely deployed as a joke, so that it cannot be assigned any non-joke semantics for the foreseeable future. That is the unusual part. The standards body did not merely tolerate the teapot; it wrote the teapot into the standard as a hole that must stay empty. Google’s search engine keeps its own tribute at google.com/teapot, which pours when you tilt your phone.

Which other status codes have a sense of humour?

Status codes with a story, official and otherwise
CodeNameStandingThe story
418I’m a teapotReserved by RFC 9110The one above. An April Fools RFC that outlived its joke.
451Unavailable For Legal ReasonsOfficial, RFC 7725 (2016)Proposed by Tim Bray for content blocked by court order or government demand. The number is a deliberate nod to Ray Bradbury’s Fahrenheit 451, the temperature at which books burn. Funny and grim at once, which is the point.
402Payment RequiredOfficial but reserved for future use since 1997Defined in HTTP/1.1 for a micropayment system that never arrived. Nearly thirty years later it is still waiting, and a handful of API companies now use it anyway.
420Enhance Your CalmNever officialTwitter’s original rate-limit response, borrowed from the film Demolition Man. Retired in favour of the standard 429 Too Many Requests, which arrived in RFC 6585 in 2012.
444No Responsenginx onlyNot a response at all: nginx closes the connection without sending anything, and logs 444 so operators know it did so on purpose.
999Request DeniedLinkedIn onlyLinkedIn’s answer to scrapers. Outside the defined 1xx to 5xx range entirely, which is its own kind of joke.
7xxDeveloper ErrorsA GitHub repository, never a proposalA community list of the codes developers wish existed: 725 It works on my machine, 750 Didn’t bother to write docs, 787 Further funding required.

How do you get a 418 from laurelinlabs.com?

Ask this site for coffee. https://www.laurelinlabs.com/coffee returns status 418 with a plain-text teapot, an Accept-Additions header listing the milk, syrup and sweetener it would accept if it were not a teapot, and an X-Teapot: permanently header for the avoidance of doubt. Send Accept: application/json and it answers as a problem-details document instead. POST stands in for BREW, since this framework only routes the standard verbs. From a terminal:

curl -i https://www.laurelinlabs.com/coffee
curl -i -H "Accept: application/json" https://www.laurelinlabs.com/coffee

The endpoint is marked noindex and kept out of the sitemap, because to a crawler a 418 is an error and the correct behaviour is to leave it alone. The teapot is also named in the comment at the top of every page’s source, next to an ASCII portrait of the author, for the people who read source.

Why does a joke status code matter to a site about being the answer?

Because the whole of technical SEO rests on status codes being honest. A 200 is a promise that there is something here worth indexing; a 301 is a promise that the thing moved; a soft 404 that returns 200 is a lie that costs crawl budget and trust. 418 is the reminder, written into the standard by people who clearly enjoyed their work, that these numbers were made by humans for humans to read. A site that gets its status codes right, including the one that refuses coffee, is a site a machine can believe. That belief is what the trust signals pillar is built on, and it is a better reason to keep the teapot than nostalgia.

Frequently asked questions about 418 i'm a teapot

Is HTTP 418 a real status code?

It is real in the sense that matters: RFC 9110, the current HTTP semantics standard, reserves 418 so it can never be assigned non-joke semantics, and most HTTP libraries know its name. It was never a standard error condition; it comes from RFC 2324, an April Fools protocol for coffee pots published in 1998.

Should a production website ever return 418?

Only where a joke is acceptable and no client depends on the answer. Some sites use it for automated requests they refuse to serve, which works because crawlers treat any 4xx as an error. Never use it in place of a meaningful code such as 403, 404, 429 or 503, and keep 418 endpoints out of the sitemap and marked noindex, as laurelinlabs.com/coffee is.

What other HTTP status codes are jokes or Easter eggs?

451 Unavailable For Legal Reasons is official (RFC 7725) and named after Fahrenheit 451; 420 Enhance Your Calm was Twitter's rate-limit code from Demolition Man; 444 is nginx closing the connection silently; 999 is LinkedIn refusing scrapers from outside the defined range; and the unofficial 7xx list includes 725 It works on my machine. 402 Payment Required is real but has been reserved for future use since 1997.