Skip to content
Back to skills

Http Video Streaming Headers

ASecurity

Fix "Failed to load video" errors when network requests succeed (200/206 status). Use when: (1) Video element shows error but DevTools shows successful requests, (2) Videos download correctly via curl but fail in browser, (3) Range requests work but video won't play, (4) Building CDN/media server for video streaming. The root cause is often missing Accept-Ranges header which browsers need for video seeking and streaming.

  • 265 stars
  • 0 votes
  • 0 copies
  • 4 views
  • Added May 27, 2026
developmentrustbash

Works with

  • claude code
  • cli

Security analysis

A96/100
  • mediumUses curl or wget to download content

Pro shows the line behind each finding and how to fix it

Scanned May 27, 2026

npx -y skills add divinevideo/divine-mobile --skill http-video-streaming-headers --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Http Video Streaming Headers?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Http Video Streaming Headers
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/divinevideo-http-video-streaming-headers/badge)](https://www.skillsdirectory.com/skills/divinevideo-http-video-streaming-headers)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: http-video-streaming-headers
description: |
  Fix "Failed to load video" errors when network requests succeed (200/206 status).
  Use when: (1) Video element shows error but DevTools shows successful requests,
  (2) Videos download correctly via curl but fail in browser, (3) Range requests
  work but video won't play, (4) Building CDN/media server for video streaming.
  The root cause is often missing Accept-Ranges header which browsers need for
  video seeking and streaming.
author: Claude Code
version: 1.0.0
date: 2026-01-29
---

# HTTP Video Streaming Header Requirements

## Problem
HTML5 video elements fail to play with "Failed to load video" error even though
network requests show successful 200/206 responses. The video file downloads
correctly when tested with curl, but browsers refuse to play it.

## Context / Trigger Conditions
- Video element fires `onerror` event despite network success
- DevTools Network tab shows 200 or 206 status for video requests
- `curl -O <video-url>` downloads a valid MP4 file
- Video plays locally when downloaded
- Error message is generic: "Failed to load video" or media error code 4

## Solution

### Required Headers for Video Streaming

1. **`Accept-Ranges: bytes`** (CRITICAL)
   - Tells browser that range requests are supported
   - Without this, browsers may not attempt range requests for seeking
   - Add to ALL video responses, even full (200) responses

2. **`Content-Type: video/mp4`** (or appropriate MIME type)
   - Must match actual video format
   - Browser uses this to select decoder

3. **`Content-Length`** (for full responses)
   - Required for browser to know file size
   - Enables progress indicators and seeking calculations
   - Note: For 206 responses, this should be partial content size

4. **For Range Requests (206 Partial Content)**:
   - `Content-Range: bytes START-END/TOTAL`
   - Status code MUST be 206, not 200

### Server Implementation

```rust
// Fastly Compute@Edge example
resp.set_header("Accept-Ranges", "bytes");
resp.set_header("Content-Type", "video/mp4");

// For full responses only (not 206):
if resp.get_status() != StatusCode::PARTIAL_CONTENT {
    resp.set_header("Content-Length", file_size.to_string());
}
```

### CDN Considerations

- Edge caches may strip or modify headers
- Verify headers reach the client, not just origin
- Fastly/CloudFront can serve range requests from cached full content
- Test with `curl -I -H "Range: bytes=0-1023"` to verify 206 response

## Verification

```bash
# Check Accept-Ranges header
curl -I https://cdn.example.com/video.mp4 | grep -i accept-ranges
# Expected: accept-ranges: bytes

# Test range request support
curl -I -H "Range: bytes=0-1023" https://cdn.example.com/video.mp4
# Expected: HTTP/2 206 with Content-Range header

# Verify partial download works
curl -H "Range: bytes=0-100" https://cdn.example.com/video.mp4 | wc -c
# Expected: 101 (bytes 0-100 inclusive)
```

## Example

**Before (broken)**:
```
HTTP/2 200
content-type: video/mp4
x-custom-header: value
```
Video fails to load in browser.

**After (working)**:
```
HTTP/2 200
content-type: video/mp4
content-length: 1443199
accept-ranges: bytes
```
Video plays correctly with seeking support.

## Notes

- Even if your CDN handles range requests automatically, you should still
  include `Accept-Ranges: bytes` in the response headers
- Some browsers are more forgiving than others; Safari often requires
  proper range support while Chrome may work without
- HTTP/2 responses may have headers lowercased (this is normal)
- For HLS/DASH streaming, the manifest and segments all need proper headers
- Mobile browsers are particularly strict about video headers

## References
- [MDN: Range Requests](https://developer.mozilla.org/en-US/docs/Web/HTTP/Range_requests)
- [MDN: Accept-Ranges](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Accept-Ranges)
- [HTTP 206 Partial Content](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/206)

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…