Quick answer: A 416 Range Not Satisfiable means the server cannot return the byte range you asked for, most often because the start offset is past the end of the resource. Read the Content-Range header on the 416 response to get the real size, then request a range that fits. A successful range request returns 206 Partial Content, not 416.

What the status code means

A range request lets a client fetch part of a resource with the Range header, such as Range: bytes=200-1000, which is how resume downloads and chunked fetching work. When the range is valid, the server returns 206 Partial Content with the requested bytes and a Content-Range header describing them.

A 416 is the server saying the requested range does not overlap the resource at all. The offsets fall outside the bytes that exist, so there is nothing to return. This is not a permission or body error; the request reached the right resource, but its window points past it.

Why it happens

The common cause is a start offset larger than the resource size, for example requesting bytes=5000- from a file that is only 1234 bytes long. This shows up when a client resumes a download with a stored offset, but the resource has since changed, been truncated, or replaced by a smaller version. A hard-coded offset or a stale length produces the same result.

A malformed range can also trigger it, though most servers reject malformed syntax with 400 rather than 416. The reliable signal is the response header: a 416 carries Content-Range: bytes */<size>, where the asterisk marks an unsatisfiable range and the number is the current total length.

How to inspect the request

Check the exact Range header value against the resource size. Fetch the resource metadata or a zero-length request to confirm the current Content-Length, then compare it with the first offset. Read the 416 response's Content-Range header rather than trusting a stored size, because the server reports the authoritative length.

If the resource is dynamic, assume its size can change between calls and revalidate before resuming. Confirm whether the failure is a single bad offset or every range request, since the latter points to a wrong URL or an empty resource.

Symptoms, causes, and fixes

Symptom Likely cause Fix
416 on a resumed download Stored offset past new size Read Content-Range and restart
416 with a hard-coded offset Offset exceeds the resource Derive the range from current length
Works once, then fails Resource changed or truncated Revalidate size before each resume
Every range request fails Wrong URL or empty resource Check the endpoint and body
206 stops and turns to 416 Length cache went stale Refresh Content-Length

Fixing the client

Treat the 416 response as the source of truth: parse the total length from Content-Range: bytes */<size> and rebuild the request with offsets inside that bound. When resuming, never assume a saved offset is still valid; revalidate first, and if the resource changed, restart from zero.

Avoid hard-coded byte positions, and clamp your end offset to one less than the total length when the server uses inclusive bounds. If you only need the whole resource, dropping the Range header and sending a normal GET removes the failure.

Verify with a real request

After the change, send the range request and assert the status is 206 and that the returned Content-Range matches the bytes you expected. A scenario can run the request as an ordered step, assert the status and headers, and keep the evidence. For offline work, a local mock can return 416 for an out-of-bounds offset and 206 for a valid one while recording requests.

The mock models your client behavior, not the real server's rules, so the final check is still a live request. Powerduck sends these requests through the local main process without browser CORS limits, runs status and header assertions at each step, and can record mock traffic. For more, see the API debugging guide hub.

Honest limits

A green scenario proves that one range now fits the current resource; it does not prove the resource stays that size, and a mock cannot reproduce a real server's handling of a changing file. Keep the live check as the source of truth, and if a verification script is missing, mark that step unverified rather than passed.

Frequently asked questions

What is the difference between 416 and 206? A 206 returns the requested partial bytes; a 416 means the range does not overlap the resource, so no bytes are returned.

How do I find the real size? Read the Content-Range header on the 416 response, which uses bytes */<size>, or request the resource metadata and check Content-Length.

The bottom line

A 416 is a window that points past the resource: the byte range's offset exceeds the current size. Read the Content-Range header for the authoritative length, revalidate before resuming, and rebuild the range inside the bound or drop the header for a full GET. Confirm the fix with a 206 assertion and a live request, and the 416 stops coming back.