Chunked Transfer Encoding Through a Proxy: What Can Change Between Connections
ColdProxy Team8 min read

Chunked transfer encoding can be removed or recoded by an HTTP-aware intermediary, so client-visible chunks prove framing on one connection only.
Different chunk sizes on two connections can be normal. Chunking is message framing for one HTTP/1.1 connection. An HTTP-aware intermediary can read that framing, recover the body, and choose new framing for the next connection without changing the body itself.
Key takeaways
- A chunk size describes the next piece of the HTTP/1.1 message body on one connection. It is not a packet size, compression ratio, or billing unit.
- A zero-sized chunk ends the data-chunk sequence. A trailer section may follow; an empty line then closes the chunked coding.
- Because
Transfer-Encodingis hop by hop, an intermediary can remove chunking or create different chunk boundaries on its outgoing connection. - Compare decoded body bytes or a body hash when you need to test content equality. Compare raw chunks only when you are testing framing on a named hop.
What does chunked transfer encoding delimit?
Chunked transfer encoding lets an HTTP/1.1 sender transmit a body without declaring its complete length first. The sender writes a chunk size in hexadecimal, may append an optional chunk extension, then writes a carriage-return and line-feed pair, that many body bytes, and another line ending. It repeats the pattern, writes a zero-sized chunk, adds any trailer section, and finishes with an empty line.
This small synthetic trace has two data chunks. The visible \r\n sequences stand for the HTTP line endings in the decoded message syntax:
A\r\nframe-test\r\n4\r\nbody\r\n0\r\n\r\nA is hexadecimal for 10, so the decoded body is frame-testbody. The size lines, separators, terminal zero, optional trailer section, and final empty line are framing; none is part of that decoded body. The trailer section is optional.
RFC 9112 puts the boundary plainly: "Transfer-Encoding is a property of the message, not of the representation." The standard also says chunked coding is specific to each connection; an HTTP-aware intermediary can carry the same representation data onward in a newly framed message.
Why can chunk boundaries change through a proxy?
Transfer-Encoding is a hop-by-hop field. As the MDN reference explains, each segment of a multi-hop connection can use a different value. An HTTP-aware intermediary therefore does not need to preserve the incoming hexadecimal sizes or the position of each boundary.
Consider an origin that sends three chunks. An intermediary may read all three, stream the same body onward as five chunks, or send a known Content-Length instead. The receiving client cannot work backward from its five chunks and prove how the origin framed the earlier message. It can prove only what arrived on its own connection.
There is an important HTTPS limit. With ordinary HTTP CONNECT, TLS runs end to end between the client and target through an opaque byte tunnel. The proxy cannot inspect or rechunk the enclosed HTTP message unless it terminates or intercepts TLS. A client-side HTTP trace describes that tunneled exchange, not a separate proxy-to-target HTTP message.
What did three client-side HTTP/1.1 observations show?
On September 4, 2026, we made three credential-free requests to the public ColdProxy My IP page with no explicit proxy configured. The responses carried no Content-Encoding and included Connection: close. The test saved framing measurements and a body hash, but no response body or response-derived network-identifying values.
All three connections negotiated HTTP/1.1. Their responses returned HTTP 200 with Transfer-Encoding: chunked, no Content-Length, no Content-Encoding, two data chunks, a zero-sized terminal chunk, and no trailers. Each dechunked body was 148,362 bytes and produced the same SHA-256 hash. The raw data-chunk sizes were different:
- Observation 1 — 128,978 bytes, then 19,384 bytes.
- Observation 2 — 128,986 bytes, then 19,376 bytes.
- Observation 3 — 128,988 bytes, then 19,374 bytes.
The first chunk varied by 10 bytes, while the second shifted by the same amount in the opposite direction. Total length and SHA-256 hash stayed fixed.
The test observed only the client-facing connection to a public page. Paid proxy connections, origin framing, packets, speed, traffic accounting, and the component that chose the boundaries were outside its scope.
How should two different traces be compared?
Suppose one engineer captures a response beside the origin and another captures what a client receives through an HTTP-aware intermediary. One trace has three chunks; the other has six. That difference alone does not show corruption.
First compare the status and representation metadata that should remain meaningful end to end. Then decode the transfer framing and compare the body length and a cryptographic hash. If those match, the changed boundary positions are normally a framing difference. If the decoded bodies differ, investigate content negotiation, transformations, partial responses, or actual corruption instead of blaming chunk count.
Treat every raw trace as evidence about one named connection. Record where the capture was made, which HTTP version was negotiated, and which intermediaries could interpret HTTP at that point. Without those details, "the response had four chunks" is incomplete evidence.
How is chunked transfer encoding different from Content-Length?
Both mechanisms let an HTTP/1.1 recipient find the end of a message body, but they make different commitments:
- Content-Length — for a message that carries a body, declares its length as a decimal number of bytes before the body is sent. The recipient knows the expected length immediately.
- Transfer-Encoding: chunked — sends hexadecimal sizes and data chunks, then a zero-sized last chunk, any trailer section, and the terminating empty line. The sender does not need the final length when the first chunk is written.
RFC 9112 forbids a sender from including Content-Length in any message that contains Transfer-Encoding. When an intermediary decodes chunked input and knows the complete output length, it can legitimately use Content-Length on the next hop. The reverse is also possible when it needs to begin forwarding before the full output length is known.
This comparison is about message delimitation. Whether the connection is later reused is a separate question covered in our guide to HTTP keep-alive with proxies.
Is transfer framing the same as compression?
No. Transfer framing tells a recipient how to find and reconstruct a message body on one connection. Content coding changes the representation bytes, commonly to reduce their size, and is described by fields such as Content-Encoding.
A response can be compressed and chunked, uncompressed and chunked, compressed with a fixed length, or neither. If you need to compare encoded and decoded byte counts, use the separate guide to Accept-Encoding and body size. A chunk count cannot substitute for either measurement.
Do HTTP/2 and HTTP/3 use chunked transfer encoding?
No. RFC 9113 says HTTP/2 uses DATA frames and cannot use HTTP/1.1 chunked transfer coding. RFC 9114 says transfer codings are not defined for HTTP/3 and forbids the Transfer-Encoding field. An HTTP/1.1 chunk trace therefore establishes the protocol on that connection only; it does not establish the protocol on another connection.
The 2024 HTTP Archive HTTP chapter gives useful scale, with clear limits on what its dataset represents. It measured 15% of requests over HTTP/1.1 and 85% in its combined HTTP/2+ group for HTTP/2 and HTTP/3. CDNs served 54% of more than 1.3 billion measured requests. Fewer than 4% of CDN-served requests used HTTP/1.1, compared with up to 29% of requests not served from a CDN node. The dataset shows HTTP/1.1 and HTTP/2+ coexisting across measured requests; it does not measure protocol choices on multiple hops of one exchange.
How can you inspect chunked transfer encoding safely?
Use only a public endpoint or a system you are authorized to test. The official curl manual documents --raw as the option that disables curl's normal decoding of HTTP content and transfer encodings. This one-line command asks for HTTP/1.1, requests no content coding, saves response fields separately, and preserves the raw body framing:
curl --http1.1 --raw --header "Accept-Encoding: identity" --dump-header headers.txt --output response.raw https://coldproxy.com/tools/my-ip/The current response can change, so do not assume this page will always use chunked framing. Check headers.txt first. If it contains Transfer-Encoding: chunked, inspect response.raw with a binary-safe or hexadecimal viewer. The header file can also contain Set-Cookie or other sensitive response fields, so redact or delete it before sharing. Do not open an untrusted body as executable content.
For a useful record:
- Save the UTC time, target URL, client version, and negotiated HTTP version.
- Record only
Transfer-Encoding,Content-Length, andContent-Encoding. Redact cookies, credentials, and identifying fields before retaining or sharing the header dump. - Parse each hexadecimal chunk size, confirm the zero-sized last chunk, process any trailers, and confirm the final empty line with no unexplained trailing bytes.
- Decode the framing, then record the decoded length and hash rather than retaining sensitive body data.
- Repeat the request and compare both the framing sequence and decoded hash.
Adding a proxy option to this HTTPS command normally creates an opaque CONNECT tunnel; it does not by itself create an HTTP-aware rechunking hop. A framing comparison requires an authorized intermediary that terminates and forwards the HTTP message, with each capture point labeled. Our cURL proxy setup guide covers ordinary client configuration.
What should a framing test conclude?
A chunk trace answers a narrow but useful question: how one HTTP/1.1 message was delimited on one connection. It does not identify packet boundaries, prove upstream chunk sizes, measure compression, or explain connection reuse.
Start by naming the observed connection. Then separate raw framing from decoded body bytes. If the body hash is stable while chunk sizes move, report a framing difference rather than a content change. That conclusion is modest, reproducible, and far more useful than treating every changed chunk count as a proxy fault.
Frequently Asked Questions
What does Transfer-Encoding: chunked mean?
It means an HTTP/1.1 message body is sent as a sequence of size-prefixed chunks. Each size is written in hexadecimal. The zero-sized last chunk ends the chunk data; optional trailers and a final empty line complete the coding, so the recipient can identify the message boundary.
Can a proxy change chunk sizes?
Yes, if the proxy can interpret the HTTP message on that connection. Transfer encoding is hop by hop, so an intermediary may decode incoming chunks and choose different boundaries or a fixed content length for its outgoing message. A normal opaque CONNECT tunnel cannot inspect the enclosed exchange with the target HTTPS endpoint.
Is chunked transfer encoding compression?
No. Chunking frames a message body for one HTTP/1.1 connection. Compression changes the representation bytes and is described separately, usually with Content-Encoding. The two mechanisms can appear together or independently, so chunk count does not reveal a compression ratio or decoded body size.
Does HTTP/2 use chunked transfer encoding?
No. HTTP/2 uses binary frames rather than the HTTP/1.1 chunked syntax, and HTTP/3 has its own frame layer as well. Because framing is connection-specific, an HTTP/1.1 chunk trace does not establish whether another connection used HTTP/2 or HTTP/3.


