Skip to main content
411

Length Required

Active
RFC 9110 §15.5.12Since 1997AWS S3, CDNs, reverse proxies, legacy APIs, file upload services

HTTP 411 Length Required indicates the server refuses to accept the request without a defined Content-Length header. Defined in RFC 9110 §15.5.12. The client must include Content-Length to specify the request body size. Common in APIs that pre-allocate resources, AWS S3 PUT operations, and proxies enforcing request smuggling protections.

Description

The 411 Length Required status code indicates that the server refuses to accept the request without a defined Content-Length header field. The client MAY repeat the request if it adds a valid Content-Length header field containing the length of the request body in the new request.

This status code exists because some servers need to know the exact size of the request body before they begin processing it. Reasons include pre-allocating buffer space, enforcing upload size limits before transfer begins, preventing certain classes of HTTP request smuggling attacks, and supporting legacy infrastructure that cannot handle chunked transfer encoding.

The distinction between 411 and 413 (Content Too Large) is important: 411 means the server cannot even evaluate whether the body is acceptable because it doesn't know the size. 413 means the server knows the size and it's too large. A request that triggers 411 might succeed with Content-Length added, while a 413 requires reducing the payload.

In modern HTTP, Transfer-Encoding: chunked allows sending data without knowing the total size upfront. However, servers returning 411 explicitly reject this approach — they require the deterministic Content-Length header regardless of whether chunked encoding is technically valid HTTP. This is a server policy decision, not a protocol violation by the client.

Notably, AWS S3 requires Content-Length for PUT requests and will return 411 if it's missing, even though chunked encoding is valid HTTP/1.1. Many CDNs and reverse proxies similarly enforce Content-Length requirements as a defense against request smuggling and to enable accurate request routing decisions.

Examples

PUT request missing Content-Length
http
PUT /bucket/object.bin HTTP/1.1
Host: s3.amazonaws.com
Authorization: AWS4-HMAC-SHA256 Credential=AKIA.../aws4_request
Transfer-Encoding: chunked
Content-Type: application/octet-stream

a
Hello Worl
5
d!!!!
0
411 response — Content-Length required
http
HTTP/1.1 411 Length Required
Content-Type: application/xml
Connection: close

<?xml version="1.0" encoding="UTF-8"?>
<Error>
  <Code>MissingContentLength</Code>
  <Message>You must provide the Content-Length HTTP header.</Message>
  <RequestId>A1B2C3D4E5F6</RequestId>
</Error>
POST request without Content-Length through a strict proxy
http
POST /api/v1/uploads HTTP/1.1
Host: api.example.com
Content-Type: multipart/form-data; boundary=----WebKitFormBoundary
Transfer-Encoding: chunked
Authorization: Bearer token_abc123

------WebKitFormBoundary
Content-Disposition: form-data; name="file"; filename="data.csv"
Content-Type: text/csv

id,name,value
1,foo,100 ------WebKitFormBoundary--
411 response — proxy enforcement
http
HTTP/1.1 411 Length Required
Content-Type: application/json
X-Request-Id: req_7f8a9b2c
Connection: close

{"error": "length_required", "message": "The Content-Length header is required for this endpoint. Transfer-Encoding: chunked is not supported.", "documentation_url": "https://docs.example.com/errors/411"}
Correct request with Content-Length included
http
PUT /bucket/object.bin HTTP/1.1
Host: s3.amazonaws.com
Authorization: AWS4-HMAC-SHA256 Credential=AKIA.../aws4_request
Content-Length: 15
Content-Type: application/octet-stream

Hello World!!!!
200 response — request accepted with Content-Length
http
HTTP/1.1 200 OK
Content-Type: application/xml
ETag: "a1b2c3d4e5f6g7h8"
x-amz-request-id: EXAMPLE123456789

<?xml version="1.0" encoding="UTF-8"?>
<PutObjectOutput>
  <ETag>"a1b2c3d4e5f6g7h8"</ETag>
</PutObjectOutput>

Edge Cases

  • AWS S3 returns 411 for PUT requests without Content-Length even though chunked encoding is valid HTTP/1.1 — this is a policy decision, not a protocol error by the client.
  • Some reverse proxies (HAProxy, Nginx in certain configurations) reject chunked requests without Content-Length to prevent HTTP request smuggling attacks (CL.TE and TE.CL desync).
  • HTTP/2 and HTTP/3 do not use Content-Length the same way — framing is built into the protocol. A 411 is primarily an HTTP/1.1 concern, but misconfigured servers may still return it for HTTP/2 requests.
  • Streaming uploads (where the total size is unknown at send time) are fundamentally incompatible with servers that require Content-Length. Workaround: buffer the entire body, compute length, then send.
  • Some CDNs (Cloudflare, Akamai) may add Content-Length on behalf of the client by buffering the request, making 411 transparent to the origin — but this adds latency and memory pressure.
  • Zero-length bodies still need Content-Length: 0. A DELETE or POST with no body but missing Content-Length may trigger 411 on strict servers.
  • Load balancers that enforce Content-Length may reject WebSocket upgrade requests or gRPC streams that rely on chunked framing — causing silent failures rather than clean 411 responses.

When You'll See This

  • Uploading a file to AWS S3 using PUT without specifying Content-Length
  • Sending a POST request through a strict reverse proxy that rejects chunked encoding
  • Streaming data to a legacy API that pre-allocates buffers based on declared body size
  • Making API calls through a WAF (Web Application Firewall) that requires Content-Length for request smuggling prevention
  • Submitting multipart form data through a CDN that doesn't support chunked forwarding
  • Zero-byte POST or DELETE requests missing the Content-Length: 0 header on strict servers
  • Client libraries that use chunked encoding by default (e.g., older curl versions with --data-binary @-) hitting S3-compatible object stores

Implementation References

LanguageConstant
Gohttp.StatusLengthRequired
Rusthttp::StatusCode::LENGTH_REQUIRED
Pythonhttp.HTTPStatus.LENGTH_REQUIRED
Node.jshttp.STATUS_CODES[411]
.NETHttpStatusCode.LengthRequired
JavaHttpURLConnection.HTTP_LENGTH_REQUIRED
PHPResponse::HTTP_LENGTH_REQUIRED (Symfony)
Ruby:length_required (Rack)

History

Introduced in HTTP/1.1 (RFC 2068, January 1997) alongside chunked transfer encoding. Carried forward unchanged through RFC 2616 (1999) and refined in RFC 9110 (June 2022, §15.5.12). Originally motivated by servers that needed to pre-allocate I/O buffers; now primarily used as a security control against request smuggling and by object stores (S3) that compute checksums from declared length.

Related Status Codes

Related Headers

FAQ

Why does AWS S3 return 411 when I use chunked transfer encoding?

S3 requires Content-Length for PUT operations because it uses the declared length to compute checksums (Content-MD5), allocate storage, and verify transfer integrity before committing the object. Chunked encoding means the total size is unknown until the final chunk arrives, which conflicts with S3's write-ahead integrity model. The fix is to buffer your data, compute the byte length, and include Content-Length in the request. For large uploads where buffering is impractical, use S3's multipart upload API instead — each part requires Content-Length but you don't need to know the total upfront.

How does 411 Length Required relate to HTTP request smuggling?

Request smuggling exploits ambiguity between Content-Length and Transfer-Encoding headers when a proxy and backend disagree on where one request ends and the next begins (CL.TE or TE.CL desync). Servers and proxies that enforce 411 — requiring Content-Length and rejecting chunked encoding — eliminate this entire attack class by removing the ambiguity. If every hop agrees on a single, explicit length, there's no room for desynchronization. This is why security-conscious proxies often return 411 rather than attempting to handle both mechanisms.

What's the difference between 411 Length Required and 413 Content Too Large?

411 means the server cannot process the request because it doesn't know how big the body is — Content-Length is missing. The request might be perfectly fine once the header is added. 413 means the server knows exactly how big the body is (Content-Length was provided) and it exceeds the server's configured limit. The fix for 411 is adding Content-Length. The fix for 413 is reducing payload size, using compression, pagination, or a chunked upload API that accepts smaller parts.