← Blog.backToBlog

hls.js Not Working? Fix Errors Free + Test Stream Online

7 min read

Common hls.js Problems at a Glance

Isolate the stream: if our free online M3U8 player plays the URL, the bug is your integration — not the playlist. Debug steps below.

hls.js is the JavaScript library most web players use to play HLS in browsers that don't support it natively. When it fails, the cause is usually one of a few things: the library didn't load, it was called before it was ready, the browser can't decode the media, or the stream itself is unreachable. This guide walks through debugging each, in the order worth checking.

Fixing Hls is not defined

The most common startup error is Hls is not defined (or Hls is undefined). It means your code ran before the hls.js script finished loading. Fixes:

  • Make sure the hls.js <script> tag loads before your player code.
  • If loading from a CDN, confirm the URL is correct and the CDN is up.
  • With bundlers, import Hls from 'hls.js' and call it after the module resolves.

Check Browser Support First

Always check Hls.isSupported() before creating an instance. If it returns false, the browser lacks Media Source Extensions. On Safari, don't use hls.js at all — set the video element's src to the .m3u8 directly, since Safari plays HLS natively. A robust player branches on both cases.

Enable Debug Logging

When something fails silently, turn on verbose logging. Pass debug: true in the Hls config:

const hls = new Hls({ debug: true });

This logs playlist loading, segment fetching, buffer management, and error recovery to the console — usually revealing exactly where the pipeline breaks.

Understanding hls.js Error Events

hls.js emits an Hls.Events.ERROR event with a specific type. The common ones:

ErrorMeaning
MANIFEST_LOAD_ERRORCan't fetch the playlist (URL/CORS)
FRAG_LOAD_ERRORA segment failed to load (most common)
BUFFER_APPEND_ERRORCodec/decode problem
KEY_LOAD_ERRORCan't load the decryption key

Handling and Recovering from Errors

hls.js separates fatal and non-fatal errors. For fatal ones, you can attempt recovery instead of failing outright: call hls.startLoad() to recover a network error, or hls.recoverMediaError() for a media error. Listen to the ERROR event, check data.fatal and data.type, and branch accordingly — this is what makes a player resilient on real networks.

Typical hls.js Failure Causes

hls.js fails when MSE is unavailable, the playlist is not valid HLS, CORS blocks segment reads, or the stream is DRM-only. Console logs usually name the fatal event type — read them before swapping libraries.

End users can bypass embedding issues by using a maintained online player: player. Developers should test the raw m3u8 in multiple browsers. Related: HTML5 internals, CORS.

Quick Isolation Steps

  1. Does Safari native play the same URL?
  2. Does the m3u8 fetch without CORS errors?
  3. Are segments 200?
  4. Is the page HTTPS mixed-content free?
  5. Is another extension breaking MSE?

If native Safari works and Chrome fails with CORS, fix headers. If both fail with 403, fix auth. If both decode-error, inspect codecs/DRM.

Production Hardening Tips

Pin hls.js versions intentionally, surface hls.js error events to your logging, and provide a desktop fallback message when the browser path cannot work. Do not promise plugin-free playback for DRM catalogs.

Practical Checklist

Before you close the tab: confirm the URL still returns 200, the tool finished without a forced account wall, and the result plays in a second app. Keep a short authorized sample for regression after CDN changes. Rights still apply — free tools do not create free rights.

Related Tools on This Site

Use the online player to preflight, the downloader to merge segments, and the converter when you need a portable MP4. Prefer client-side paths when CORS allows; fall back to FFmpeg when the browser is blocked.

Common Mistakes to Avoid

Do not chain three random free websites for the same job — each re-encode costs quality and raises watermark risk. Do not ignore 403/CORS as “player bugs.” Do not archive paywalled DRM catalogs. Document the one path that worked so your team does not rediscover failures under deadline pressure.

Notes for Operators

Write the successful command or UI path into your runbook with the date and the CDN hostname. Future incidents then start with a known-good baseline instead of a blank search box. Re-test after certificate, token, or edge-rule changes.

Notes for Operators

Write the successful command or UI path into your runbook with the date and the CDN hostname. Future incidents then start with a known-good baseline instead of a blank search box. Re-test after certificate, token, or edge-rule changes.

Notes for Operators

Write the successful command or UI path into your runbook with the date and the CDN hostname. Future incidents then start with a known-good baseline instead of a blank search box. Re-test after certificate, token, or edge-rule changes.

Bottom Line

Use the free browser path for quick authorized work, keep a desktop escape hatch for CORS and long jobs, and never confuse “the tool worked” with “you have the rights.” Document the path that succeeds so your team stops rediscovering the same failure under deadline pressure. Start with the matching tool page on this site, then fall back to FFmpeg when the browser cannot complete the job.

Frequently Asked Questions

Why do I get Hls is not defined?
Your code ran before hls.js loaded — load the script first or import it properly.

Does hls.js work in Safari?
You don't need it — Safari plays HLS natively; use the video src directly.

What does FRAG_LOAD_ERROR mean?
A segment failed to load, often due to CORS, a 404, or the network.

How do I debug hls.js?
Set debug: true and read the console, or test the stream in our player.