A resumed HTTP transfer can corrupt a local result without any malformed bytes if the resource changes between requests. The first response may supply bytes from one representation while a later range response supplies offsets from another. If-Range exists to bind the resumed range to the representation that produced the stored prefix.
This is a representation-identity problem rather than a transport-framing problem. Byte offsets only have stable meaning relative to a particular representation. A syntactically valid 206 Partial Content response can still be unusable for recombination when its bytes belong to a different version.
Byte offsets inherit representation identity
Suppose a client receives the first 1,000 bytes of a 10,000-byte representation before the connection ends. It stores those bytes and later asks for the remainder:
GET /archive.bin HTTP/1.1
Range: bytes=1000-If /archive.bin has not changed, a supported and satisfiable byte-range request can return a 206 response containing the missing suffix. The client can combine the stored prefix and returned suffix.
If the selected representation changed before the second request, offset 1000 now refers to the new representation. Concatenating the old prefix with the new suffix creates a byte sequence that corresponds to neither version.
Content-Range does not solve that identity mismatch. It describes the range carried by a partial response and the complete length when known. A response such as Content-Range: bytes 1000-9999/10000 identifies positions within the representation selected for that response; it does not assert that a separately stored prefix came from the same representation.
If-Range makes range processing conditional
A client that retained a strong entity tag from the initial response can send it with the resume request:
GET /archive.bin HTTP/1.1
Range: bytes=1000-
If-Range: "v17"The condition changes the server’s treatment of Range. When the If-Range validator matches the selected representation and the range is otherwise applicable, the server can process the range and return partial content. When the validator does not match, the server ignores Range and sends the complete selected representation as a normal successful response.
That fallback matters. A failed If-Range condition does not produce the 412 Precondition Failed behavior associated with failed write-oriented preconditions such as If-Match. Its purpose is to avoid a second round trip when a partial resume is no longer safe. The client either receives bytes suitable for completing the stored representation or receives a complete current representation that replaces the partial state.
The response status therefore carries part of the recombination decision. A 206 response indicates partial representation data. A 200 response after an If-Range mismatch represents the complete selected representation, so treating its body as the requested suffix would be incorrect.
Strong validation is required for entity tags
HTTP requires an entity tag used in If-Range to be strong. A weak tag such as W/"v17" cannot be generated by a client as an If-Range entity-tag value.
That restriction follows from the operation being protected. Safe byte recombination needs representation equivalence strong enough for range assembly. Weak validators are permitted to group representations that are semantically equivalent while differing in representation data. Such equivalence can be sufficient for cache validation in contexts where byte-for-byte identity is unnecessary, but it is not sufficient for splicing byte ranges.
For an entity-tag If-Range condition, the server uses the strong comparison function. Exact opaque-tag text alone is not enough if validator weakness differs; a weak validator does not satisfy the required comparison.
An HTTP-date can also appear in If-Range, but its use is more constrained. A client must not generate that form when it has an entity tag for the representation, and the date must qualify as a strong validator under HTTP semantics. Entity tags are therefore the more direct identity mechanism when the origin supplies them.
Range support remains optional
If-Range does not force a server to implement range requests. HTTP range support is optional, and a server can ignore Range in cases allowed by the protocol.
Accept-Ranges: bytes advertises support for byte ranges, but it is advisory rather than a promise that every future request will receive 206. The selected content can change, server policy can change, or another intermediary can participate in a later exchange.
This means resume logic needs to interpret the actual response rather than infer it from the request. A client asking for a suffix can receive a full 200 response even apart from an If-Range mismatch. Correct handling depends on response semantics, not on the assumption that a sent Range header guarantees partial content.
An unsatisfiable supported range has another outcome. When the relevant preconditions are true but the range cannot be satisfied for the selected representation, the server should send 416 Range Not Satisfiable. For byte ranges, a 416 response can include the current complete length as Content-Range: bytes */length.
Conditional GET and conditional range serve different decisions
A normal cache revalidation asks whether a stored response can continue to stand in for the current selected representation. If-None-Match commonly expresses that condition. A matching validator on a GET can lead to 304 Not Modified, with no representation content transferred.
A resume request asks a different question: can newly transferred bytes be combined with bytes already stored? If-Range keeps that decision attached to range processing. If the representation still matches, partial transfer remains useful. If it changed, a complete transfer is more useful than a precondition failure because the old partial bytes can no longer complete the current representation.
HTTP evaluates ordinary request preconditions before range processing. Range is considered only when the request without Range would otherwise produce a 200 response. This ordering prevents range mechanics from overriding a conditional result such as 304.
The distinction also keeps If-Range narrow. It is not a general cache validator and has no effect without Range. A server must ignore If-Range when no Range field is present, and an origin server must ignore it for a target resource that does not support range requests.
Recombination needs metadata as well as bytes
A resumable client needs more than an offset counter. The stored partial data must remain associated with the validator that identifies its source representation. Losing that association leaves the client unable to establish that a later suffix belongs to the same representation.
The local state can be modeled as a tuple:
(resource identifier, validator, stored byte interval)The resource identifier locates the target, the validator constrains representation identity, and the interval records which portion is already present. Each component answers a separate question.
This model also exposes a failure mode in download managers that persist partial bytes but discard response metadata. A later process can know that 8 MiB exists locally yet have no protocol evidence that byte 8 MiB in the current representation follows those stored bytes. Sending an unconditional range request in that state optimizes transfer volume by accepting an identity risk.
A safe policy can instead restart the transfer when no suitable validator remains. That choice may transfer more data, but it avoids constructing a hybrid object from unrelated representation versions.
Resume correctness ends at the representation boundary
If-Range protects HTTP representation recombination under the protocol’s validator semantics. It does not establish that the resource’s application-level meaning stayed constant, nor does it verify a completed file against an independent cryptographic digest unless the application supplies such a check.
Content codings also matter because ranges address representation data. A client that stores encoded bytes and later resumes must keep its range accounting aligned with the representation actually selected and transferred. Changes in representation selection can invalidate offsets even when the underlying application resource appears conceptually unchanged.
The central constraint is therefore precise: partial transfer is safe to splice only when the client has evidence that both byte sets belong to the same representation. If-Range turns that evidence into a server-side branch between partial continuation and complete replacement, keeping a transport optimization from silently crossing a representation-version boundary.