Skip to content

Error: Failed to execute 'appendBuffer' on 'SourceBuffer': The HTMLMediaElement.error attribute is not null. #7116

Description

@martinstark

What do you want to do with Hls.js?

Catch video playback errors while playing video with hls.js

What have you tried so far?

I'm listening to errors on hls.js through the public event API:

hls.on(Hls.Events.ERROR, onHlsError);

However, I'm catching an error that looks like this:

{
  "type":"mediaError",
  "parent":"main",
  "details":"bufferAppendError",
  "sourceBufferName":"video",
  "error":{
    "stack":"Error: Failed to execute 'appendBuffer' on 'SourceBuffer': The HTMLMediaElement.error attribute is not null.\n at bufferController.appendExecutor
  }
}

The original error is what has me confused. I expect hls.js to raise an error immediately if the video element throws an error, so I am not listening directly to videoElement.addEventListener("error", ...) to avoid error reporting race conditions between hls.js and native errors.

However, in this particular case hls.js will not raise the natively thrown error, instead it will retry appending the segment 5 times, then raise the bufferAppendError instead of the native error. This creates a misleading error, since it doesn't indicate the root cause that made the videoElement throw.

When playing video through hls.js, is the integration expected to look for errors on both the native video element, as well as errors thrown through the hls.js api? If I need to listen to two separate sources for playback errors, that risks creating race-conditions that will hide errors from one source or the other.

Activity

  1. added
    Needs TriageIf there is a suspected stream issue, apply this label to triage if it is something we should fix.
    on Mar 21, 2025
  2. robwalch commented on Mar 22, 2025

    @robwalch
    Collaborator

    That has been the expectation up to this point. The app provides hls.js with a media element and for the most part is expected to manage it and use it (not hls.js) to control playback. One example is the demo page, which listens to video element errors and calls recoverMediaError by default. I could name a few other integrations that share media element event listeners between hls.js and Safari HLS playback so this isn't uncommon. All that said, it is not ideal or intuitive. Thank you for calling this out.

    What version are you running and have you reproduced this issue with the latest version (v1.6.0-rc.1 or higher)?

    Please file bugs rather than a questions to report issues. Steps to reproduce with expect/actual behavior help us understand why there is a media element error in the first place and avoid, recover, or stop further action with a fatal error.

    Appending should be avoided if the media element is in an error state to avoid further errors. To maintain some backwards compatibility with applications that handle it themselves we should defer forwarding of a media element error until just before it would interfere with MSE operations or the like. It may then also make sense to block those operations until the media is reset (detached and reattached).

  3. martinstark commented on Mar 23, 2025

    @martinstark
    Author

    That has been the expectation up to this point
    All that said, it is not ideal or intuitive. Thank you for calling this out

    Thanks for the response and sentiment! I would very much like to only have to listen to errors in one place, since catching them in two places leads to difficulties in parsing or reporting the errors to tracking systems, in order to get an overview of what actually went wrong. It's not clear if the hlsjs error, or the native error, is the one that should be surfaced, so to speak.

    Please file bugs rather than a questions to report issues.

    In this case, the error happens to a tiny subset of thousands of plays, I do not have enough data to provide a way of reproducing this issue, or I would. It did make me wonder about the specifics around figuring out when things to wrong in or around hlsjs, though. Looks like the first thing I'll need to do to collect better data is to start including the native error in these cases as well.

    have you reproduced this issue with the latest version (v1.6.0-rc.1 or higher)?

    I cannot deploy a RC to production, so I have no way of confirming if it's been fixed there, but I'm eagerly awaiting the stable 1.6 release (primarily since, last time I checked, it'll expose the internal ended event for "live" manifests. MSE often fails to fire "ended" in these cases when playing with hls.js. Inspecting the internal hlsjs state it will indicate it has ended, but the videoelement refuses to fire the event). Yet again, unfortunately this is just an observation I have, without a reliable way of reproducing.

    Appending should be avoided if the media element is in an error state to avoid further errors

    Yeah, I suppose I could create a ticket to fix this, since it should be easy to fix even if there is no way to reliably reproduce our particular issue. E.g. check for errors before attempting to append a buffer.

    In addition to that, should I create a feature request for enabling listening to errors exclusively through hlsjs? E.g. "Make hls.js raise errors on unrecoverable media errors".

  4. robwalch commented on Mar 23, 2025

    @robwalch
    Collaborator

    Isolating which browsers and browser versions impact you will help troubleshooting.

    The media error is usually a code 2 "decode" error. There are platform-specific cases related to MSE append order or overlap. It is not always invalid media passing through the decoder.

    I'm sure we could find related issues with very similar error behavior. We may get reproduction steps from one. That'll let us verify against the latest build and workshop solutions.

    We rarely can attribute these errors to a specific segment, playlist, or sequence of appends. So capturing timely detailed information is first and foremost what this issue raises. Error resolution that can be turned off or customized can follow.

  5. martinstark commented on Mar 23, 2025

    @martinstark
    Author

    I'll update our error handling and add more details once I have them

  6. robwalch commented on Mar 23, 2025

    @robwalch
    Collaborator

    Here's the list of issues sighting the same SourceBuffer error "Failed to execute appendBuffer on SourceBuffer: The HTMLMediaElement.error attribute is not null" with my summary notes:

    One way to repro this issue in order to improve error handling, would be to intentionally trigger a media decode error by appending bad data for a particular segment. We could then see if a media source reset followed by a variant switch or skipping segments near the playhead or last append recovers playback. Logging playhead position and buffered ranges on "error" is something else we could add.

  7. added this to the 1.6.1 milestone on Apr 1, 2025
  8. removed
    Needs TriageIf there is a suspected stream issue, apply this label to triage if it is something we should fix.
    on Apr 1, 2025
  9. removed this from the 1.6.1 milestone on Apr 1, 2025
  10. added this to the 1.7.0 milestone on Jan 26, 2026
  11. robwalch commented on Jan 26, 2026

    @robwalch
    Collaborator

    There's been some recent work, related to this issue, that handles MediaSource closing or being found in an "ended" state on SourceBuffer error. We haven't looked at whether the HTMLMediaElement error occurs first. We should add handling for that in response to this issue. In that latest changes, #7702, the media element error occurs after the first append to error because of a media pipeline parsing issue.

  12. robwalch commented on Apr 9, 2026

    @robwalch
    Collaborator

    Closing with features introduced in #7702. An error event with MEDIA_SOURCE_REQUIRES_RESET is triggered when the MediaSource is closed as a result of a past or upcoming HTMLMediaElement error.

    hls.on(Hls.Events.ERROR, onHlsError);
    
    {
      type: "mediaError",
      parent: "main" | "audio", // HLS Playlist (main = Variant, audio = Alternate media option)
      details: "mediaSourceRequiresReset",
      sourceBufferName: "video" | "audio" | "audiovideo", // demuxed or "audiovideo" = muxed
      frag?: <Fragment appending>,
      error:{
        message: "MediaSource closed while media attached" | "MediaSource readyState <closed | ended> during SourceBuffer..."
    + "<  !fatal ? '- triggering recovery' >< mediaError ? ' with HTMLMediaElement Error: ' + HTMLMediaElementError.message >"
      },
      fatal: <boolean>
    }
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions