Skip to main content
Troubleshooting

How to fix "No playable sources found" in HLS streaming

Seeing a black screen with the dreaded text "No compatible source was found for this media" or "No playable sources found"? This generic error—often thrown by Video.js or standard HTML5 players—means the player gave up trying to decode your M3U8 file. This guide breaks down the four technical root causes and provides practical steps to fix your stream infrastructure.

When a web-based video player encounters a fatal error before playback can even commence, it typically displays a fallback message like "No playable sources found." Because players like Video.js abstract the underlying complexity, this error hides a variety of distinct network, manifest, and decoding failures. To fix it, you need to act like a detective and isolate the exact point of failure.

Root Cause 1: CORS Policy Blocking the Manifest

By far, the most common reason for this error is a Cross-Origin Resource Sharing (CORS) block. Modern browsers enforce strict security policies that prevent JavaScript (like an HLS web player) from reading data from a different domain unless that domain explicitly permits it.

If your website is https://my-video-site.com and your M3U8 stream is hosted on https://cdn.streaming.net, the CDN must respond with CORS headers. If it doesn't, the browser blocks the fetch() request. The player receives a network error, assumes the source is invalid or unreachable, and throws the "No playable sources found" error.

Diagnosis

Open Chrome Developer Tools (F12) -> Console. Look for red text saying something like: "Access to fetch at '...' from origin '...' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource."

The Fix

You must configure your media server or CDN to send permissive CORS headers. This needs to apply to .m3u8 files, .ts segments, and encryption keys.

CORS Configuration Examples

For Nginx: Add this to your location block handling media files:

location ~ \.(m3u8|ts|m4s)$ {
    add_header 'Access-Control-Allow-Origin' '*' always;
    add_header 'Access-Control-Expose-Headers' 'Content-Length' always;
    if ($request_method = 'OPTIONS') {
        add_header 'Access-Control-Allow-Origin' '*';
        add_header 'Access-Control-Allow-Methods' 'GET, HEAD, OPTIONS';
        add_header 'Content-Type' 'text/plain charset=UTF-8';
        add_header 'Content-Length' 0;
        return 204;
    }
}

For AWS CloudFront / S3: You need to attach a CORS policy to your S3 bucket that permits the GET method from the * (or your specific) allowed origin.

Root Cause 2: Missing or Unsupported Codecs

If CORS is perfectly configured, the next culprit is often an unsupported codec. The "No playable sources" error can mean exactly that: the player downloaded the M3U8 master playlist, inspected the declared codecs="..." tags, and realized the browser lacks the capability to decode any of them.

For example, if you encode a stream exclusively in HEVC (H.265) and attempt to play it on an older version of Chrome Desktop, the browser's Media Source Extensions (MSE) will reject it.

Always include at least one H.264 (AVC) and AAC audio stream in your master playlist to ensure universal compatibility. Example safe codec string: codecs="avc1.42E01E,mp4a.40.2"

Root Cause 3: Malformed M3U8 Playlists or 404s

Sometimes the manifest downloads successfully, but the contents are garbage, or they point to segments that don't exist.

  • Missing `#EXTM3U` header: The very first line of a valid M3U8 file must be exactly `#EXTM3U`. If there is a blank line before it, or if it's missing, strict parsers will reject the file immediately.
  • Broken relative paths: If your master playlist points to 720p/index.m3u8, but the web server configuration is stripping paths or redirecting incorrectly, the player will hit a 404 Not Found error when trying to fetch the media playlist.
  • Missing MIME types on the server: If your server returns the M3U8 file with a Content-Type: text/plain or application/octet-stream instead of the expected application/vnd.apple.mpegurl or application/x-mpegURL, some players will refuse to parse it.

Root Cause 4: HTTPS Mixed Content Restrictions

Modern browsers block "Mixed Content" for security reasons. This occurs when your website is loaded securely over HTTPS (e.g., https://my-video-site.com), but the video source URL inside the player configuration is explicitly set to HTTP (e.g., http://cdn.streaming.net/video.m3u8).

The browser's network stack will kill the HTTP request before it even leaves the computer. The player will then report that no source could be found.

  • The Fix: Ensure your entire streaming pipeline—from the player page, to the M3U8 manifest URL, to the individual TS segments referenced inside the manifest—is served exclusively over HTTPS.

Step-by-Step Troubleshooting Checklist

When faced with this error, follow this exact debugging sequence:

  1. Check the Network Tab: Open DevTools (F12) -> Network. Reload the page. Look for requests to .m3u8 files. Are they colored red? Are they returning 404 (Not Found) or 403 (Forbidden)?
  2. Check the Console Tab: Look for CORS errors or Mixed Content warnings.
  3. Test in VLC or Safari: Paste the exact M3U8 URL into a desktop player like VLC Media Player, or Safari on a Mac. If it plays there but not in Chrome, you have a CORS or Codec issue. If it fails everywhere, the URL is broken or the server is down.
  4. Download and Inspect the Manifest: Manually download the .m3u8 file and open it in a text editor. Verify the `#EXTM3U` header is present. Ensure the paths to the `.ts` segments look logically correct.
  5. Verify Server MIME Types: Ensure your origin server is configured to serve `.m3u8` as `application/vnd.apple.mpegurl` and `.ts` as `video/MP2T`.

Conclusion

The "No playable sources found" error is the web player's way of throwing its hands in the air. By systematically checking CORS policies, confirming codec compatibility, verifying HTTPS integrity, and validating the manifest structure, you can pinpoint the exact failure point and restore healthy playback.