Content-Length
The HTTP Content-Length header indicates the size of the message body in bytes, appearing in both requests and responses.
Usage
The Content-Length header communicates the exact byte size of the HTTP message body. Clients rely on this value to know when a response has been fully received, making the connection available for reuse in persistent connections under HTTP/1.1.
When a server sends a response with a known body size, the Content-Length header allows the client to allocate the right amount of memory and display accurate progress indicators during downloads. A mismatch between the declared length and the actual body size signals a truncated or corrupted transfer.
This header is mutually exclusive with chunked Transfer-Encoding. When a server streams a response of unknown size, chunked encoding replaces a fixed content length. Under HTTP/2 and HTTP/3, framing handles message boundaries at the protocol level, but Content-Length remains valid for body size validation.
The value is a single non-negative integer representing the number of octets (bytes) in the message body.
Example
A server returns a 3,495-byte JSON response. The client reads exactly 3,495 bytes before considering the message complete.
Content-Length: 3495
A POST request sends a form body. The Content-Length header tells the server how many bytes to expect in the request body.
POST /submit HTTP/1.1
Host: example.re
Content-Type: application/x-www-form-urlencoded
Content-Length: 27
field=value&other=something
A response using chunked transfer encoding omits the Content-Length header entirely. The Transfer-Encoding header takes precedence.
Transfer-Encoding: chunked
Troubleshooting
Transfer failures and connection errors often trace back to an incorrect or conflicting Content-Length value.
Transfer interrupted or partial download. The client receives fewer bytes than Content-Length declares and reports a truncated response. Common causes: the origin closes the connection early, a proxy timeout cuts the transfer, or the server miscalculates the body size. Run
curl -v https://example.re/fileand compare theContent-Lengthheader value with the actual bytes received (shown in the transfer summary). A mismatch confirms the issue.Chunked encoding and Content-Length both present. Sending both Transfer-Encoding: chunked and Content-Length in the same response violates the HTTP specification. Clients must ignore Content-Length when Transfer-Encoding is present, but not all implementations follow this rule. Remove Content-Length when using chunked encoding. In nginx, chunked encoding is applied automatically when the body size is unknown, and nginx omits Content-Length in that case. Custom application code or middleware that sets both headers needs correction.
Content-Length wrong after middleware modifies the body. Middleware that injects content (analytics scripts, security tokens, debug toolbars) changes the body size without updating Content-Length. The browser either truncates the visible content or waits for bytes that never arrive. Move Content-Length calculation to the final stage after all body modifications complete. In Express.js, the
compressionmiddleware handles this automatically. In custom setups, remove Content-Length and rely on chunked encoding instead.HEAD response carries wrong Content-Length. A HEAD response must include the same Content-Length the corresponding GET response would carry, but with no body. Some frameworks generate HEAD responses with a Content-Length of 0 or omit the header entirely. Verify by comparing
curl -I https://example.re/resource(HEAD) withcurl -s -o /dev/null -w '%{size_download}' https://example.re/resource(GET body size). Mismatched values break download managers and caching proxies that rely on HEAD to determine resource size.Diagnosing Content-Length issues with curl. Run
curl -v https://example.re/resourceto see the Content-Length header and the transfer byte count in the verbose output. The lineContent-Length: Nshows the declared size. At the end,bytes receivedshows the actual transfer. Add-o /dev/nullto discard the body and focus on headers. For compressed responses, remember that Content-Length reflects the compressed size, not the original size.
See also
- RFC 9110: HTTP Semantics - Content-Length
- Transfer-Encoding
- Content-Encoding
- HTTP connection management
- HTTP headers