Immediate Fix
The “206 Partial Content” status is actually a success message for Range Requests, but it often causes audio playback to fail if headers are misconfigured. To fix this immediately, ensure your S3 object has the correct Content-Type and CORS policy.
| Setting | Required Value | Description |
|---|---|---|
| Content-Type | audio/mpeg or audio/wav | Must match the actual file format. |
| AllowedHeaders | Range, Authorization | Required for byte-range requests. |
| ExposeHeaders | Content-Range, Content-Length | Allows the browser to read the audio stream. |
Update your S3 Metadata via the AWS CLI if the files are already uploaded:
aws s3 cp s3://your-bucket/audio.mp3 s3://your-bucket/audio.mp3 \
--metadata-directive REPLACE \
--content-type "audio/mpeg"
Technical Explanation
When a browser plays audio, it doesn’t download the whole file at once. It sends a “Range” header asking for specific bytes. AWS S3 responds with a 206 Partial Content status and the requested chunk.
The “error” usually occurs because the browser expects a specific byte range that S3 cannot satisfy, or the connection is severed before the next chunk is delivered. This is common when using <audio> tags in Chrome or Safari.
Common triggers include missing Accept-Ranges: bytes headers or a mismatch in the Content-Length. If you are using a proxy or a CDN, it must be configured to pass the Range header through to S3.

Alternative Methods
1. Use AWS CloudFront
Directly serving audio from S3 can be unstable for high-traffic apps. Using CloudFront handles Range Requests more efficiently. Ensure you enable “Forward Headers” for “Origin” and “Range” in your Cache Policy.
2. Generate Pre-signed URLs
If your bucket is private, ensure your pre-signed URLs are valid and include the necessary permissions. Sometimes, the signature becomes invalid if the browser attempts to re-request a range after a specific timeout.
3. Check CORS Configuration
If you see a 206 status but the console shows a CORS error, update your bucket’s CORS JSON:
[
{
"AllowedHeaders": ["*"],
"AllowedMethods": ["GET", "HEAD"],
"AllowedOrigins": ["*"],
"ExposeHeaders": ["Content-Range", "Accept-Ranges", "Content-Length"]
}
]