A client that has only part of an HTTP representation faces a consistency problem when it asks for the missing bytes later. Byte offsets are meaningful only against the representation whose bytes established those offsets. If the selected representation changes between requests, combining an old prefix with a new suffix can produce data that no server ever emitted.
If-Range attaches representation identity to that partial-retrieval boundary. When its validator matches, the server can process the accompanying Range field. When it does not match, the server ignores Range and sends the complete selected representation through the normal successful response path instead of returning a failed-precondition response.
That fallback is the defining property. If-Range is not a general cache validator and not a write guard. It is a conditional switch between partial transfer and complete transfer.
Byte offsets belong to one representation
Consider a client that received the first 1,000 bytes of a 10,000-byte representation before its connection ended. The response also carried a strong entity tag:
HTTP/1.1 200 OK
ETag: "rev-8"
Content-Length: 10000The client can later ask for the remaining bytes:
GET /archive.bin HTTP/1.1
Range: bytes=1000-
If-Range: "rev-8"If "rev-8" still strongly matches the entity tag of the selected representation, the server can process the range and, when the other range conditions hold, return partial content:
HTTP/1.1 206 Partial Content
ETag: "rev-8"
Content-Range: bytes 1000-9999/10000The client now has pieces tied to the same validator. The range offset and the stored prefix refer to one representation data sequence.
Suppose the resource instead changed to "rev-9". Processing bytes=1000- against that new representation could make the stored prefix unsafe to combine with the returned suffix. The same numeric offset says nothing about semantic continuity across two representation versions.
If-Range makes that version boundary explicit.
A failed condition removes the Range field
The failure behavior differs from ordinary HTTP preconditions. If an If-Match condition fails on a request where that precondition applies, the normal result is 412 Precondition Failed. A false If-Range condition has another effect: the recipient ignores Range.
Conceptually, the branch is:
validator matches
-> process Range
-> partial response can be 206
validator does not match
-> ignore Range
-> send the current complete representationFor a satisfiable range request whose condition matches, a server that supports the range unit should send 206 Partial Content. For a false If-Range condition, range processing disappears from the request semantics, so the response is the result that the GET would have produced without Range, commonly 200 OK with the complete current representation.
This design avoids an extra round trip. A client using If-Match with Range could detect a changed representation through 412, but it would then need another request for the current complete representation. If-Range encodes the client’s preferred recovery directly: partial data if the old representation is still current, complete data otherwise.
Strong validators protect recombination
An entity tag in If-Range cannot be weak. The client must not generate a field such as:
If-Range: W/"rev-8"The restriction follows from the operation being protected. Recombining byte ranges requires confidence that the representation data belongs to the same version, not merely that two representations are equivalent under weaker cache-validation semantics.
For an entity-tag form, the server evaluates If-Range with the strong comparison function. A weak tag therefore cannot establish the identity required for safe range continuation.
This is stricter than a use case that only needs to decide whether a cached response is semantically reusable. A weak validator can be useful when representation changes are insignificant for cache validation, but that tolerance is incompatible with joining byte sequences at fixed offsets.
A validator also needs correct server semantics. An origin that emits the same strong entity tag for representation data that has changed violates the premise on which range recombination depends. If-Range cannot compensate for an invalid strong-validator implementation.
Date validators have a narrow admissible case
If-Range can carry an HTTP date instead of an entity tag, but the date form has stricter conditions than simply copying any Last-Modified value.
A client must not generate a date-form If-Range when it has an entity tag for the corresponding representation. It also must not use the date unless that date qualifies as a strong validator under HTTP’s validator rules.
When a server evaluates a date-form If-Range, the condition is true only if the supplied date is a strong validator and exactly matches the selected representation’s Last-Modified value. Otherwise the condition is false and Range is ignored.
That exact-match rule differs from If-Unmodified-Since, whose comparison is based on whether the selected representation was modified after the supplied date. If-Range is binding a partial byte sequence to a validator, so an exact validator match is the relevant relation.
Entity tags avoid dependence on modification-time resolution and are therefore the preferred form when available.
Content coding changes the byte coordinate system
HTTP byte ranges address the octets of representation data after any content coding has been applied. They do not address the decoded payload that an application might eventually consume.
If a representation is transferred with a content coding, a request such as:
Range: bytes=5000-refers to byte offset 5,000 in the encoded representation data. A server cannot treat that as offset 5,000 in the decoded source and still claim ordinary HTTP byte-range semantics.
This detail strengthens the need for stable validators across resumed transfers. A change in content coding can change the byte sequence and its offsets even when the decoded information appears equivalent. A strong validator used for If-Range must remain consistent with the representation data being selected.
Content negotiation introduces the same boundary more broadly. Request fields can influence which representation is selected. A resumed request that negotiates a different representation is not made safe merely because the target URI is unchanged. Validator matching is the protocol mechanism that determines whether the stored partial data still belongs to the selected representation.
Range support remains optional
If-Range does not force a server to implement range requests. HTTP range handling is optional, and a server can ignore Range in cases permitted by the specification.
The dependency is explicit: a client must not generate If-Range without Range, and a server must ignore If-Range when no Range field is present. An origin also ignores If-Range for a target resource that does not support range requests.
Accept-Ranges: bytes can advertise support, but it is advisory rather than a promise that every future request will receive partial content. The representation can change, server conditions can change, or another intermediary can participate in a later exchange.
A robust protocol interpretation therefore treats 206 as the observable confirmation that partial content was returned. The presence of Range, If-Range, or a prior Accept-Ranges field does not by itself establish that the response body is partial.
Unsatisfiable ranges are evaluated only on the matching branch
Range validity and satisfiability matter after the conditional machinery permits range processing.
If the If-Range validator matches and the requested byte range is unsatisfiable for the selected representation, a supporting server should return 416 Range Not Satisfiable. For byte ranges, that response should include a Content-Range value carrying the current complete length when known:
HTTP/1.1 416 Range Not Satisfiable
Content-Range: bytes */10000If If-Range is false, however, the server ignores Range. The unsatisfiable range no longer controls the response because the request proceeds as an ordinary GET of the complete selected representation.
That ordering prevents a stale client’s obsolete offsets from turning a version change into a range error. The more useful response is the current complete representation, which replaces the stale partial copy.
Multiple ranges preserve the same identity requirement
A Range field can request several byte ranges. A successful multi-range response can use multipart/byteranges, with each body part carrying its own Content-Range.
If-Range applies to the range request as a whole. It does not validate each requested interval independently. Either the validator permits processing the range set against the selected representation, or the range field is ignored.
This matches the data model: all requested offsets refer to one selected representation. There is no meaningful protocol state in which some offsets belong to "rev-8" while others are silently taken from "rev-9" and then combined as one resumed object.
Servers retain discretion to reject or ignore pathological range sets, including requests with many small or overlapping ranges under conditions described by HTTP. Validator success does not remove those range-processing constraints.
Partial storage needs metadata, not only bytes
A client implementing resumable retrieval needs more than a file fragment and a byte count. It needs metadata that ties the fragment to the representation from which it came.
At minimum, the stored state commonly includes the validator and the byte interval represented by the local data. The validator is what makes a later If-Range request meaningful. Without it, the client cannot ask the server to distinguish continuation of the same representation from replacement by a newer one.
This boundary also limits naive download-resume logic. A local file length of 4 MiB does not prove that Range: bytes=4194304- is safe. That offset becomes reusable only when the client has a sound basis for associating the local bytes with the current selected representation.
The protocol deliberately keeps that basis opaque. A strong entity tag can be a revision token, digest-derived value, or another server-defined identifier. The client does not need to interpret it; it needs to preserve and return it exactly as a validator.
If-Range encodes a recovery preference
Conditional requests often expose a failed condition as a distinct response. If-Range instead encodes a two-outcome transfer preference: continue from stored partial data if representation identity still holds, or replace that partial state with the current complete representation.
That distinction keeps the mechanism narrow. It does not provide transaction isolation, guarantee resumability, require range support, or define persistence behavior for a download manager. It only connects a Range request to a strong representation validator and specifies what happens when that connection no longer holds.
The observable consequence is precise. Matching identity preserves the possibility of a partial transfer. Changed identity removes the byte-range request from consideration, preventing stale offsets from being applied to a different representation.