HTTP headers · Request and response
Content-Length
Content-Length is the exact body size in bytes, used to delimit messages and detect truncation.
Key facts
| Type | Request and response |
|---|---|
| Unit | Octets (bytes), not characters |
| Conflict | Forbidden with <code>Transfer-Encoding</code> |
| Chunked | No Content-Length on a chunked body |
| Compression | Measures the encoded body |
| Truncation | A short body is a protocol error |
| Standard | RFC 9110 §8.6 |
Framing, not metadata
HTTP/1.1 needs to know where a message ends. Content-Length gives the number of octets in the body, allowing the receiver to read exactly that many. It is not a character count: a UTF-8 string with non-ASCII letters is longer in bytes than in characters.
It describes the body after transfer encoding and content encoding. If gzip is applied, the header reports the compressed size, not the original size. When both Content-Length and Transfer-Encoding are present, the message is ambiguous and must be rejected.
Truncation and smuggling
A body shorter than the declared length is a truncation error. A body longer than the declared length leaves extra octets that the next request may mistake for its own — the classic request-smuggling condition when a proxy and a server disagree about framing.
For streams and dynamically generated pages, chunked transfer encoding is the correct choice because the final size is unknown when headers are sent. Frameworks usually set the header for you; set it manually only when the exact byte length is known.
Frequently asked questions
Is Content-Length the same as file size?
For an uncompressed static file, yes. For a compressed or transformed response, it is the size on the wire.
Why does my server reject both Content-Length and Transfer-Encoding?
The combination is a smuggling risk. RFC 9112 requires the message to be treated as invalid.