Introduction
Cloudflare Stream provides video hosting, encoding, and delivery infrastructure. Stream handles video upload, transcoding to multiple formats, storage, and adaptive bitrate delivery. Errors can occur at any stage: upload failures (file format, size limits), transcoding issues (unsupported codecs), playback errors (manifest problems, DRM), and delivery failures (bandwidth, regional restrictions). Understanding which stage fails helps target the fix.
Symptoms
- Video upload fails with format or size error
- Uploaded video stuck in "processing" or "pending" status
- Playback returns error or blank player
- Video quality options not appearing
- Stream playback buffered or stalled
- Error messages: "Video not found", "Playback error", "Upload failed"
- DRM-protected content not playing
- Regional restrictions blocking playback
Common Causes
- Unsupported video format or codec
- Video file exceeds size limits
- Upload URL or tus protocol issue
- Transcoding stuck or failed
- Manifest (HLS/DASH) generation error
- Incorrect video UID or token
- Playback token expired or invalid
- Missing or incorrect DRM configuration
- Viewer's network blocking Stream domains
- CORS or content policy restrictions
Step-by-Step Fix
- 1.Check video upload status:
Navigate to: Stream > Videos in Cloudflare Dashboard
``` # Video states: # - pending: Upload in progress # - processing: Transcoding active # - ready: Available for playback # - error: Upload or transcoding failed
# If stuck in pending/processing for extended time, issue exists ```
- 1.Verify video file format and codec:
```bash # Check video properties ffprobe -v error -show_format -show_streams input.mp4
# Cloudflare Stream supports: # - Formats: MP4, MOV, AVI, MKV, WebM, FLV # - Video codecs: H.264, H.265/HEVC, VP8, VP9 # - Audio codecs: AAC, MP3, Opus, Vorbis
# Unsupported codecs cause transcoding failures ```
- 1.Check file size limits:
``` # Stream upload limits: # - Single file: 10GB (Enterprise can be higher) # - Tus upload chunks: recommended 5-50MB
# For large files, use tus resumable uploads ```
- 1.Use proper upload method:
```bash # Direct upload (small files): curl -X POST \ -F file=@video.mp4 \ -H "Authorization: Bearer API_TOKEN" \ https://api.cloudflare.com/client/v4/accounts/ACCOUNT_ID/stream/videos
# Tus resumable upload (large files): # 1. Create upload session curl -X POST \ -H "Authorization: Bearer API_TOKEN" \ -H "Tus-Resumable: 1.0.0" \ -H "Upload-Length: FILE_SIZE" \ -H "Upload-Metadata: filename dXBsb2FkXzEubXA0,name ZmlsZW5hbWU" \ https://api.cloudflare.com/client/v4/accounts/ACCOUNT_ID/stream/videos
# 2. Upload chunks to returned URL ```
- 1.Check video processing logs:
```bash # Via API - check video details curl -X GET "https://api.cloudflare.com/client/v4/accounts/ACCOUNT_ID/stream/videos/VIDEO_UID" \ -H "Authorization: Bearer API_TOKEN"
# Look for: # - status: ready/error # - error message if failed # - transcoding progress percentage ```
- 1.Verify video UID and playback URL:
```html <!-- Standard player embed --> <stream src="VIDEO_UID" controls></stream> <script src="https://embed.videodelivery.net/embed/rkx9ast1.js"></script>
<!-- Or HLS/DASH manifest directly --> https://customer-ACCOUNT_ID.cloudflarestream.com/VIDEO_UID/manifest/video.m3u8 https://customer-ACCOUNT_ID.cloudflarestream.com/VIDEO_UID/manifest/video.mpd ```
- 1.Check playback token validity:
```bash # For signed URLs (token-required playback) curl -X POST "https://api.cloudflare.com/client/v4/accounts/ACCOUNT_ID/stream/videos/VIDEO_UID/token" \ -H "Authorization: Bearer API_TOKEN" \ -H "Content-Type: application/json" \ --data '{"expiresIn": 3600}'
# Returns token for signed playback URL # Use token in URL: https://customer-ACCOUNT_ID.cloudflarestream.com/VIDEO_UID/token/TOKEN_VALUE/manifest/video.m3u8 ```
- 1.Test manifest accessibility:
```bash # Check HLS manifest curl -I https://customer-ACCOUNT_ID.cloudflarestream.com/VIDEO_UID/manifest/video.m3u8
# Should return 200 OK with m3u8 content
# Check individual segment curl -I https://customer-ACCOUNT_ID.cloudflarestream.com/VIDEO_UID/manifest/360p/video.mp4 ```
- 1.Debug player errors:
// In player JavaScript, catch errors
const player = document.querySelector('stream');
player.addEventListener('error', (event) => {
console.error('Stream error:', event.detail);
// Check error type:
// - network: Connection failed
// - decode: Codec not supported
// - source: Video not found or invalid
});- 1.Check DRM configuration:
```bash # For DRM-protected content: curl -X GET "https://api.cloudflare.com/client/v4/accounts/ACCOUNT_ID/stream/videos/VIDEO_UID" \ -H "Authorization: Bearer API_TOKEN"
# Check drm field in response # DRM requires proper license server and key configuration
// Player DRM configuration const player = new StreamPlayer({ drm: { type: 'fairplay', // or 'playready', 'widevine' licenseUrl: 'https://license.server.com' } }); ```
- 1.Verify domain access:
```bash # Stream domains must be accessible curl -I https://customer-ACCOUNT_ID.cloudflarestream.com/
# If blocked, check: # - Corporate firewall blocking stream domains # - Regional restrictions # - DNS resolution for cloudflarestream.com ```
- 1.Check CORS configuration:
```bash # For cross-origin playback curl -I https://customer-ACCOUNT_ID.cloudflarestream.com/VIDEO_UID/manifest/video.m3u8 \ -H "Origin: https://your-website.com"
# Should return proper CORS headers: # Access-Control-Allow-Origin: * ```
- 1.Enable Stream analytics:
Navigate to: Stream > Analytics
# Monitor:
# - Views per video
# - Bandwidth usage
# - Playback errors
# - Geographic distribution- 1.Test with sample video:
```bash # Upload known-good test video curl -X POST \ -F file=@test.mp4 \ -H "Authorization: Bearer API_TOKEN" \ https://api.cloudflare.com/client/v4/accounts/ACCOUNT_ID/stream/videos
# If test video works, issue is with specific source video # If test video fails, account/configuration issue ```
Verification
After applying fixes:
- 1.Video shows "Ready" status in Stream dashboard
- 2.HLS/DASH manifest accessible via curl
- 3.Player loads and plays video without errors
- 4.Multiple quality options available in player
- 5.Playback token generates valid signed URLs
- 6.Video plays across different browsers and devices
- 7.Stream analytics shows playback views