Error: 416 Requested Range Not Satisfiable — The Amazon S3 Partial Download Trap
When byte ranges go beyond object limits and integrity checks fight back.
Problem
It’s late, traffic is spiking, and your download service begins failing with cryptic 416 errors. Users report broken downloads and incomplete files:
<Error>
<Code>InvalidRange</Code>
<Message>The requested range is not satisfiable</Message>
</Error>
At first glance, this looks like an S3 outage — but it isn’t. Amazon S3 is rejecting a range request that doesn’t make sense.
Clarifying the Issue
The HTTP 416 Requested Range Not Satisfiable error occurs when the byte range specified in a request does not align with the actual size of the object.
Common causes include:
- Invalid range: The requested byte range exceeds the object’s total size.
- Mismatched ETag: The object has changed since the range request began — the ETag no longer matches.
- Incomplete multi-part uploads: Unfinished uploads can leave dangling or inconsistent object metadata.
- CDN or proxy issues: Cached metadata (like old
Content-Length
values) can cause range mismatches with the origin object.
It’s not that S3 failed — it’s that your request asked for something that no longer exists, or not in that form.
Why It Matters
The 416 error is a logical safeguard, not a failure. It’s S3’s way of protecting data integrity:
- Prevents corruption: Ensures only valid byte ranges are served.
- Preserves consistency: Guards against mismatched versions.
- Reveals hidden bugs: Identifies stale caches and malformed range logic.
- Avoids unnecessary retries: Saves bandwidth and compute during recovery.
A misaligned range can cascade into failed downloads, corrupted partials, and wasted time during high-load situations.
Key Terms
- Range Header: Sent by the client to request a specific portion of an object, e.g.
Range: bytes=0-1023
. - Content-Range Header: Returned by S3 in response to a valid partial request (HTTP 206), confirming which bytes are being sent and the object’s total size, e.g.
Content-Range: bytes 0-1023/20000000
. - ETag: A unique identifier for a specific object version used for integrity checks.
- InvalidRange: S3’s internal code corresponding to the HTTP 416 error.
Remember: the client sends a Range header to request a portion of an object, and S3 responds with a Content-Range header indicating which bytes were actually returned.
Steps at a Glance
- Check the object’s total size.
- Validate the requested range.
- Confirm the ETag hasn’t changed.
- Check for incomplete multi-part uploads.
- Add error handling and retries in client code.
Detailed Steps
1. Check the Object’s Total Size
Use head-object
to view metadata, including ContentLength
and ETag
:
aws s3api head-object --bucket my-bucket --key largefile.bin
2. Validate the Requested Range
Ensure your client’s byte range doesn’t exceed the total size:
curl -I -H "Range: bytes=0-1023" https://my-bucket.s3.amazonaws.com/largefile.bin
A valid request returns HTTP 206 Partial Content. An invalid one returns 416 Requested Range Not Satisfiable.
3. Confirm the ETag Hasn’t Changed
If your application caches ETags, verify they still match:
aws s3api head-object --bucket my-bucket --key largefile.bin --query ETag
Outdated ETags can cause failed range requests if the file changed between attempts.
4. Check for Incomplete Multi-Part Uploads
Incomplete uploads can cause inconsistencies:
aws s3api list-multipart-uploads --bucket my-bucket
aws s3api abort-multipart-upload --bucket my-bucket --key largefile.bin --upload-id <ID>
5. Add Error Handling and Retries in Client Code
A robust client should gracefully handle 416s, refresh metadata, and retry. Example in Python:
import boto3
from botocore.exceptions import ClientError
s3 = boto3.client('s3')
try:
response = s3.get_object(Bucket='my-bucket', Key='largefile.bin', Range='bytes=0-1023')
content_length = response['ContentLength']
print(f"Retrieved {content_length} bytes")
except ClientError as e:
if e.response['Error']['Code'] == 'InvalidRange':
print("Invalid range: requested bytes exceed object size. Refresh metadata and retry.")
else:
raise
Conclusion
The 416 Requested Range Not Satisfiable error isn’t an outage — it’s S3 enforcing correctness. It tells you the client’s view of the object no longer matches reality.
Ensure accurate metadata, handle ETags properly, and validate byte ranges before retrying. With these safeguards in place, you’ll turn broken downloads into reliable data delivery.
Aaron Rose is a software engineer and technology writer at tech-reader.blog and the author of Think Like a Genius.
Comments
Post a Comment