Skip to content

HTTP status code · Client errors (4xx)

416 Range Not Satisfiable

416 Range Not Satisfiable means the client asked for a part of a file, with a Range header, that does not exist, typically starting past the end. The classic case is resuming a download that was already complete, or of a file that changed on the server.

Facts about this status code
Class4xx, Client errors
Also known asRequested Range Not Satisfiable
Defined inRFC 9110 §15.5.17
Cacheable by defaultOnly with explicit Cache-Control or Expires
Safe to retryYes, with a range inside the length given in Content-Range, or without Range
Relevant headers
  • Content-Range: should state the current length, e.g. bytes */47022
  • Range: request header that asked for the unsatisfiable bytes
  • Accept-Ranges: bytes on normal responses tells clients that range requests are supported

What 416 means

RFC 9110, section 15.5.17, gives two reasons: none of the requested ranges can be satisfied, or the client asked for an excessive number of small or overlapping ranges, which the spec flags as a possible denial of service. A server answering a byte-range request with 416 should send Content-Range with an asterisk and the current length, as in Content-Range: bytes */47022, so the client learns the real size.

Servers may also ignore Range and send the whole file with 200, and many do. You rarely write 416 by hand: Go http.ServeContent and http.ServeFile, Express res.sendFile and express.static, nginx and S3 all generate it when the range is out of bounds. S3 labels it InvalidRange.

Common causes

If you are visiting the site

  • A download manager or browser tried to resume a file that had already finished downloading.
  • The file on the server was replaced by a smaller version after your partial download started.

If you run the server

  • curl -C - or wget -c resumes against a local file that is as large as, or larger than, the remote one.
  • A video player seeks using a byte offset computed from stale metadata, after the media file was re-encoded.
  • A client sends a Range request for a zero-byte file; no byte range can be satisfied when the representation is empty.
  • A CDN caches a shorter object than the origin now holds, so ranges near the end fail at the edge.

How to fix it

If you are visiting the site

  • Delete the partial file and download it again from the start.
  • Reload the page with the video or file so the player fetches fresh metadata.

If you run the server

  • Read the length from Content-Range: bytes */LENGTH in the 416 and compare it with the local partial file; if they match, the download is already complete.
  • Send If-Range with the ETag when resuming, so the server returns the full new file with 200 if it changed instead of a 416 or a corrupted mix.
  • Purge the CDN object after replacing a file with a different size.

How to send 416

You rarely need this by hand. Go http.ServeContent and http.ServeFile, Express res.sendFile and express.static, and nginx static serving answer 416 with the right Content-Range automatically.

Express (Node.js)
app.get('/files/:name', (req, res) => {
  res.set('Content-Range', 'bytes */47022');
  res.status(416).end();
});
Next.js App Router route handler
// app/files/[name]/route.ts
export async function GET() {
  return new Response(
    null,
    { status: 416, headers: { 'Content-Range': 'bytes */47022' } }
  );
}
Go net/http
mux.HandleFunc("GET /files/{name}", func(w http.ResponseWriter, r *http.Request) {
	w.Header().Set("Content-Range", "bytes */47022")
	w.WriteHeader(http.StatusRequestedRangeNotSatisfiable) // 416
})
Python FastAPI
from fastapi import FastAPI, Response

app = FastAPI()

@app.get("/files/{name}")
def get_file(name: str):
    return Response(status_code=416, headers={"Content-Range": "bytes */47022"})
Shell
# Ask for bytes past the end of a 47022-byte file
curl -sI -H 'Range: bytes=50000-' https://example.com/files/report.pdf
# HTTP/2 416
# content-range: bytes */47022

Commonly confused with

416 vs 206
206 Partial Content is the success answer to a Range request; 416 is the failure when the range is impossible.
416 vs 200
A server that ignores Range sends 200 with the full file, which is also allowed and avoids 416 entirely.

Frequently asked questions

Why does curl -C - return 416?
curl asks for bytes starting at the size of your local file. If that file is already complete, the start offset equals the remote size and no bytes remain, so the server answers 416. The download is usually done.
What should a 416 response contain?
RFC 9110 says a server answering a byte-range request with 416 should include Content-Range: bytes */LENGTH with the current size of the resource.
Can a server ignore the Range header instead?
Yes. Range support is optional, and many servers answer an unsatisfiable or unsupported range with 200 and the full body. Clients have to handle both.

Last reviewed by Arielton Oberek.