HTTP partial content, resolved
What does your Range request return?
Paste a Range header and the resource size to get the resolved byte intervals and the exact response — 206 (single or
multipart), 416, or an ignored-Range 200 — with the precise Content-Range and Content-Length. The full interactive tool also validates a
Content-Range.
The rules in brief
bytes=0-499 is the first 500 bytes (positions 0–499). bytes=500- means byte 500 to the end. Content-Length is the number of bytes actually sent.
bytes=-500 is the LAST 500 bytes, not the first. If the resource is smaller, you get all of it. bytes=-0 requests nothing and is unsatisfiable.
A satisfiable range → 206 Partial Content. None satisfiable → 416 with Content-Range: bytes */total. A malformed or ignored Range → the full 200.
Two or more satisfiable ranges return multipart/byteranges — one Content-Range per part, no single top-level one, and Content-Length covers the whole multipart body.
Resumable downloads (bytes=received-), media seeking (byte offset), and object stores / CDNs all depend on correct Range handling. Off-by-one in Content-Range breaks them.
Why it matters
Range requests power resumable downloads, media seeking, and object-store / CDN partial reads — and a single off-by-one in Content-Range breaks them. rangelab resolves the RFC 9110 rules with a disclosed method — no black box — entirely client-side, so nothing you paste is uploaded and no live request is made. It is an informational developer tool; confirm against your real server.
Frequently asked questions
What does rangelab do?
It demystifies HTTP Range (partial-content) requests. Paste a Range request header — for example bytes=0-499, bytes=500-, bytes=-500, or a multi-range like bytes=0-0,-1 — together with the resource size, and rangelab parses every byte-range spec, resolves the actual byte intervals against the size, and shows exactly what the server should return: 206 Partial Content (single or multipart/byteranges), 416 Range Not Satisfiable, or a full 200 when a malformed Range is ignored — with the precise Content-Range, Content-Length, and Accept-Ranges headers. A second mode validates a Content-Range response header. Everything runs in your browser; nothing is uploaded.
How do I read bytes=0-499?
Byte positions are zero-based and inclusive. bytes=0-499 requests the first 500 bytes — positions 0 through 499. bytes=500-999 is the next 500. bytes=500- (no end) means "from byte 500 to the end of the resource". So Content-Length for bytes=0-499 is 500, and the response carries Content-Range: bytes 0-499/<total>.
What is a suffix range like bytes=-500?
A leading minus makes it a SUFFIX range: bytes=-500 asks for the LAST 500 bytes of the resource, not bytes 0–500. If the resource is smaller than the suffix length (say 300 bytes), you simply get the whole thing. bytes=-0 requests zero bytes and is unsatisfiable. Suffix ranges are how a client grabs, say, the trailer of a file without knowing its exact length.
When does the server return 206 vs 416 vs 200?
206 Partial Content when at least one requested range is satisfiable — the body is that slice (or, for several ranges, a multipart/byteranges document). 416 Range Not Satisfiable when no range can be satisfied (for example the first byte is at or past the end of the resource); the response carries Content-Range: bytes */<total> so the client learns the real size. 200 OK (the full resource) when the Range is malformed and the server ignores it, or when the server simply chooses not to honor ranges.
What happens with multiple ranges?
A request like bytes=0-99,200-299 with more than one satisfiable range produces a 206 whose body is a multipart/byteranges document: each part has its own Content-Range header and the parts are separated by a boundary. There is no single top-level Content-Range in that case, and Content-Length covers the entire multipart body (the slices plus the boundary and part headers), so it is larger than the sum of the requested bytes. rangelab lists the per-part Content-Range lines for you.
How are out-of-range values handled?
A last-byte-pos beyond the end is clamped to the last byte (size − 1) — bytes=1000-99999 on a 1234-byte file becomes bytes 1000-1233. A first-byte-pos at or past the end makes that range unsatisfiable. If last-byte-pos is less than first-byte-pos (bytes=500-100), the whole header is invalid and SHOULD be ignored, giving a 200. rangelab shows the clamping and satisfiability for every spec.
What is Accept-Ranges, and Content-Range exactly?
Accept-Ranges: bytes is the server advertising that it supports byte ranges; Accept-Ranges: none means it will not honor them (so it answers 200). Content-Range is the response header that describes the slice being returned: bytes start-end/total (e.g. bytes 0-499/1234), bytes start-end/* when the total is not yet known, or bytes */total in a 416 response. It is valid only when start ≤ end and end < total — rangelab’s second mode checks exactly that.
Why do Range requests matter in practice?
They power three everyday things. Resumable downloads: after a dropped connection, the client re-requests bytes=<bytes-already-received>- to continue rather than restart. Media streaming and seeking: a video player jumps to a timestamp by requesting the byte offset for that point. And object stores / CDNs (S3, R2, Bunny, and friends) lean on correct Range handling for partial reads. A subtle off-by-one in Content-Range breaks all of them, which is what this tool helps you catch.
Is this exact? Is my data private?
rangelab implements the Range and Content-Range rules from RFC 9110 (HTTP Semantics), which absorbed the older RFC 7233. It evaluates statically from the values you paste and does not make a live request, so it cannot see server-specific behavior, proxies, or CDNs that bend the rules — always confirm against your real server. On privacy: this is a static page; everything you paste is processed in your browser, never uploaded, and nothing is logged.