Content-Length: the size of the body in octets
Content-Length states the size of the message body in octets. It tells the recipient where the body ends, which is what makes connection reuse possible.
At a glance
- Direction
- Both. It describes whichever body the message carries.
- Defined in
- RFC 9110
- When absent
- In HTTP/1.1 the length comes from chunked transfer encoding or from the connection closing.
- Unit
- Octets of the body as transmitted, so after any Content-Encoding is applied
- Must not appear with
- Transfer-Encoding, in the same message
- Head responses
- May state the length the body would have had, even though no body is sent.
- Mismatch risk
- Request smuggling, where a proxy and an origin disagree about where a body ends
In detail
The number counts the bytes on the wire, after compression rather than before. That is why a compressed response shows a length smaller than the file on disk, and why computing the value from the uncompressed source produces a truncated or hanging response. Anything that transforms a body must recompute the length or switch to chunked encoding.
A message must never carry both this header and Transfer-Encoding. If it does, receivers are required to treat the framing as unreliable, because the two headers describe the end of the body differently. Attackers use exactly that disagreement: a front end that trusts one header and a back end that trusts the other can be made to split a single stream into two requests, which is request smuggling.
A value that disagrees with the actual body is worse than an absent one. Too small and the recipient stops early and reads the remainder as the start of the next message; too large and it waits for bytes that never arrive until a timeout fires. Both look like an intermittent network fault rather than a header bug.
HTTP/2 and HTTP/3 frame messages themselves, so the header is informational there and must simply agree with the total size of the data frames. It is still worth sending on responses, because it is what lets a client show a progress bar rather than an indeterminate spinner.
Examples
HTTP/1.1 200 OK
Content-Type: application/json
Content-Length: 27
{"status":"ok","count":3}HTTP/1.1 200 OK
Content-Type: text/event-stream
Transfer-Encoding: chunkedNo Content-Length here, and sending one alongside Transfer-Encoding would make the framing ambiguous.
Things that catch people out
- Counting characters rather than octets breaks on any non-ASCII body, because one character can be several bytes in UTF-8.
- A HEAD response may carry the length the body would have had. Client code that allocates a buffer from the header and then waits for that many bytes will hang.
- Rewriting a body in a proxy or middleware without updating the length produces truncated responses that only appear under certain payload sizes.
Try it: HTTP Headers Checker
Check a live URL or paste headers you already have. It grades six security headers from A+ to F and lists every other header the response returned.
HTTP Headers Checker
LOCAL · Browser-OnlyView HTTP response headers for any URL
Enter any website URL to fetch and analyze its HTTP response headers. We'll automatically add https:// if needed.
Why Check Security Headers?
Security headers protect your website against common attacks like XSS, clickjacking, and MIME sniffing. They're set by your web server and cost nothing to implement. Missing security headers are one of the most common findings in security audits.
Related HTTP headers
All http headers →Transfer-Encoding: chunked framing on the connection
What chunked transfer encoding does, why it is a hop by hop property, why it must never accompany Content-Length, and why HTTP/2 forbids it entirely.
Content-Type: media type, charset and boundary
How Content-Type is structured, why the charset parameter still matters, what boundary does on a multipart upload, and how a wrong type breaks a page.
Content-Range: which bytes this partial response holds
How Content-Range describes a byte range, what the total size field means, the unsatisfied form sent with 416, and how multipart ranges are framed.
Content-Encoding: what compression was applied
What Content-Encoding declares, how it differs from Transfer-Encoding, why it changes the ETag, and how double compression happens in a proxy chain.
Content-Language: the audience a document is for
What Content-Language actually states, how it differs from the lang attribute in markup, when to list several tags, and how it pairs with Accept-Language.
Content-Disposition: download prompts and file names
How to force a download instead of inline display, how filename and filename* differ, and how to send a non-ASCII file name that survives every browser.
Tools for this
- HTTP Request Builder Free online HTTP request builder - build and test HTTP requests with custom headers and body
- HTTP Headers Checker Free online HTTP headers checker - view HTTP response headers for any URL