Today I learned about the basics of HTTP range headers.
What are HTTP range headers?
They help HTTP clients request a part or several parts of the file content.
The client can control which segments of the resource files they want and the server that supports them can provide exactly that.
The client specifies the unit and the offset ranges based on the Content-Length that the server responds with.
To know if a client support partial responses (when range headers are used), the client can inspect for a certain HTTP response header from the server. Here’s an example:
Accept-Ranges: Bytes
If the server was able to process and server the requested content range, then the client can expect a HTTP status 206 Partial Content. Else if the server cannot process the provided range, the server responds with a 4XX (416 Range Not Satisfiable) response. This is also returned if the requested range is improper (like in reverse order of malfomed)
Here’s an example snippet taken and modified from the MDN1 documentation:
➜ ~ curl https://i.imgur.com/z4d4kWk.jpg -i -H "Range: bytes=0-10" --output -
HTTP/2 206
content-type: image/jpeg
last-modified: Thu, 02 Feb 2017 11:15:53 GMT
etag: "18c50e1bbe972bdf9c7d9b8f6f019959"
x-amz-storage-class: STANDARD_IA
x-amz-cf-pop: JFK50-P6
x-amz-cf-id: unKLSEZv6qx_gPITlFbtbFAvUFQO51rK6ZJKy9PiAUWwbUzjl2vacQ==
cache-control: public, max-age=31536000
accept-ranges: bytes
age: 1234174
content-range: bytes 0-10/146515
date: Thu, 29 Jan 2026 04:16:23 GMT
x-served-by: cache-iad-kcgs7200052-IAD, cache-rtm-ehrd2290043-RTM
x-cache: Miss from cloudfront, HIT, HIT
x-cache-hits: 69, 0
x-timer: S1769660183.126144,VS0,VE1
strict-transport-security: max-age=300
access-control-allow-methods: GET, OPTIONS
access-control-allow-origin: *
server: cat factory 1.0
x-content-type-options: nosniff
content-length: 11
����C%
Some servers like imgur return the whole content (200 OK) if the requested range is improper.
curl https://i.imgur.com/z4d4kWk.jpg -i -H "Range: bytes=10-0" --output - | head -25
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0
HTTP/2 200
content-type: image/jpeg
last-modified: Thu, 02 Feb 2017 11:15:53 GMT
etag: "18c50e1bbe972bdf9c7d9b8f6f019959"
x-amz-storage-class: STANDARD_IA
x-amz-cf-pop: JFK50-P6
x-amz-cf-id: unKLSEZv6qx_gPITlFbtbFAvUFQO51rK6ZJKy9PiAUWwbUzjl2vacQ==
cache-control: public, max-age=31536000
accept-ranges: bytes
age: 1234395
date: Thu, 29 Jan 2026 04:20:04 GMT
x-served-by: cache-iad-kcgs7200052-IAD, cache-rtm-ehrd2290050-RTM
x-cache: Miss from cloudfront, HIT, HIT
x-cache-hits: 69, 0
x-timer: S1769660404.111650,VS0,VE1
strict-transport-security: max-age=300
access-control-allow-methods: GET, OPTIONS
access-control-allow-origin: *
server: cat factory 1.0
x-content-type-options: nosniff
content-length: 146515
����C
21 143k 21 31416 0 0 26364 0 0:00:05 0:00:01 0:00:04 26377
curl: (56) Failure writing output to destination, passed 1209 returned 0
These headers won’t probably be useful in day to day uses of the HTTP protocol, but they’re something that one can use during multimedia streaming or supporting pausing and resuming downloads on static files (usually large ones).
👋 ⸻ @TnvMadhav