HTTP 100 is Continue: an interim response saying the server has seen the request’s method, target and headers and wants the body. RFC 9110 section 15.2.1 defines it, and section 10.1.1 defines the Expect: 100-continue header that asks for it. It is never the end of the exchange: the final response follows once the body has arrived.
The exchange
PUT /uploads/backup.tar HTTP/1.1
Host: example.com
Content-Type: application/x-tar
Content-Length: 5368709120
Expect: 100-continue
HTTP/1.1 100 Continue
(the client sends the 5 GB body)
HTTP/1.1 201 Created
Location: /uploads/backup.tar
What makes it worth having is the answer the server can give instead: a 401, 405 or 413 before a single byte of the body crosses the network. RFC 9110 requires an origin server that receives such a request to answer at once, with either a final status or a 100, and never to wait for the body first.
Who sends Expect
- curl adds
Expect: 100-continueby itself to HTTP/1.1 uploads over 1 MB or of unknown size, waits one second for the 100, then sends the body anyway. - .NET Framework’s
HttpWebRequestsends it on POSTs by default (ServicePointManager.Expect100Continue). In .NET’sHttpClientit’s off until you setExpectContinue. - Go’s client sends it only when you set the header, and waits
Transport.ExpectContinueTimeout. - Browsers never do.
Expectis a forbidden header in the Fetch standard, sofetch()can’t set it.
Who answers it
- Node’s
httpserver sends the 100 itself unless you listen forcheckContinue; then you decide, withres.writeContinue()or a final status. - Go’s server sends it the first time the handler reads
r.Body. A handler that answers without reading never sends it. - nginx answers it when it reads the body, and strips
Expectfrom what it proxies, so the upstream never sees it.
Gotchas
- A client mustn’t wait forever. An HTTP/1.0 proxy can’t send a 100, so RFC 9110 says a client should not wait indefinitely before sending the body.
- A server that refuses the expectation answers 417 Expectation Failed, and RFC 9110 tells the client to repeat the request without
Expect. - A server that sends a 100 still owes a final status code.
- Like every 1xx, it is never cached: RFC 9111 stores only responses with a final status.
curl -T backup.tar https://example.com/uploads/ # Expect added, waits 1 s
curl --expect100-timeout 10 -T backup.tar https://example.com/uploads/ # waits up to 10 s
curl -H 'Expect:' -T backup.tar https://example.com/uploads/ # no Expect at all
server.on('checkContinue', (req, res) => { // Node: decide before the body arrives
if (Number(req.headers['content-length']) > 1e9) return res.writeHead(413).end();
res.writeContinue();
handleUpload(req, res);
});
Search 100 417 in the tool below to compare the two.