HTTP 411 is Length Required: the server refuses the request because it doesn’t carry a defined Content-Length (RFC 9110 section 15.5.12). The client may repeat it with a valid Content-Length giving the size of the body in bytes.
Why a server asks
RFC 9112 section 6.3 lets a server reject any request that has a body but no Content-Length, which in HTTP/1.1 means a body sent with Transfer-Encoding: chunked. The RFC notes that some services do this even though they understand chunked, usually because a gateway needs the length before it calls the backend and won’t buffer the whole body first. So it asks clients that know the size in advance to send Content-Length rather than chunked.
The two usual causes
A POST with no body and no header. RFC 9110 section 8.6 says a user agent normally sends Content-Length: 0 on a POST with empty content. Some clients don’t:
curl -X POST https://api.example.com/jobs/7/run # no body, no Content-Length
curl -d '' https://api.example.com/jobs/7/run # Content-Length: 0
A streamed body. A client that writes a body without knowing its size sends it chunked: Node’s http.request when you write() without a Content-Length header, curl -T - reading stdin, or Go’s client with a body whose size it can’t see.
req, _ := http.NewRequest("PUT", url, bytes.NewReader(data)) // ContentLength set for you
req, _ = http.NewRequest("PUT", url, file) // *os.File: size unknown, sent chunked
req.ContentLength = info.Size() // so set it yourself
Go fills in the length only for *bytes.Buffer, *bytes.Reader and *strings.Reader bodies.
Who sends it
- Gateways and storage APIs that must size an upload before accepting it.
- nginx, before version 1.3.9 added chunked request bodies in 2012: it answered every chunked upload with 411.
HTTP/2 and HTTP/3 frame bodies themselves and don’t need Content-Length, so 411 is mostly an HTTP/1.1 story.
Gotchas
- Count bytes, not characters.
"héllo"is 6 bytes in UTF-8. Let the HTTP library compute the header when it can: a wrongContent-Lengthis worse than none, since too small truncates the body and too large leaves the server waiting. - 411 or 413. 411 means the server needs the size before it will decide; 413 means it knows the size and it’s too big.
- Caching. 411 isn’t heuristically cacheable.
A server that requires the header, in Express:
app.put('/uploads/:name', (req, res, next) => {
if (req.get('Content-Length') === undefined) {
return res.status(411).send('Send Content-Length: chunked uploads are not accepted here.');
}
next();
});
Search 411 413 in the tool below to compare the two.