bilibili/flv.js · error · RuntimeException

MSStreamLoader: Http code invalid, ' + xhr.status + ' ' + xh

Error message

MSStreamLoader: Http code invalid, ' + xhr.status + ' ' + xhr.statusText

What it means

MSStreamLoader (IE/Edge MSStream XHR path) validates the HTTP status at readyState 2. A status outside 200-299 (and not 0) sets the loader to kError and, when no onError callback is registered, throws RuntimeException with the status code and statusText. It means the server refused or failed the segmented stream request.

Source

Thrown at src/io/xhr-msstream-loader.js:217

                    }
                }

                let lengthHeader = xhr.getResponseHeader('Content-Length');
                if (lengthHeader != null && this._contentLength == null) {
                    let length = parseInt(lengthHeader);
                    if (length > 0) {
                        this._contentLength = length;
                        if (this._onContentLengthKnown) {
                            this._onContentLengthKnown(this._contentLength);
                        }
                    }
                }
            } else {
                this._status = LoaderStatus.kError;
                if (this._onError) {
                    this._onError(LoaderErrors.HTTP_STATUS_CODE_INVALID, {code: xhr.status, msg: xhr.statusText});
                } else {
                    throw new RuntimeException('MSStreamLoader: Http code invalid, ' + xhr.status + ' ' + xhr.statusText);
                }
            }
        } else if (xhr.readyState === 3) {  // LOADING
            if (xhr.status >= 200 && xhr.status <= 299) {
                this._status = LoaderStatus.kBuffering;

                let msstream = xhr.response;
                this._reader.readAsArrayBuffer(msstream);
            }
        }
    }

    _xhrOnError(e) {
        this._status = LoaderStatus.kError;
        let type = LoaderErrors.EXCEPTION;
        let info = {code: -1, msg: e.constructor.name + ' ' + e.type};

        if (this._onError) {

View on GitHub (pinned to 42343088f2)

Solutions

  1. Verify the URL returns 200 (curl -I) and fix server-side availability or authentication.
  2. Attach an onError handler so LoaderErrors.HTTP_STATUS_CODE_INVALID is delivered to your code instead of thrown.
  3. Implement URL refresh/retry with a backup source for long-lived streams.

Example fix

// before
loader.load(url); // long-lived signed URL
// after
setInterval(() => loader.updateUrl(reSign(url)), 4 * 60 * 1000); // refresh before expiry
Defensive patterns

Strategy: retry

Validate before calling

async function ensurePlayable(url) {
    const res = await fetch(url, {method: 'HEAD'});
    if (res.status < 200 || res.status > 299) throw new Error('Bad status ' + res.status);
    return true;
}

Try / catch

try {
    player.load();
} catch (e) {
    if (/MSStreamLoader: Http code invalid/.test(e.message)) {
        setTimeout(() => { player.unload(); player.load(); }, backoffMs);
    } else throw e;
}

Prevention

When it happens

Trigger: The XHR loading the FLV stream receives 404/403/5xx headers in _xhrOnReadyStateChange (src/io/xhr-msstream-loader.js:217), typically at request open on IE/Edge where MSStream is used.

Common situations: Expired or invalid query-string auth on the media URL, stream removed from the server, or redirect to an HTML error page — surfacing only on legacy IE/Edge playback.

Related errors


AI-assisted analysis of bilibili/flv.js@42343088f2 (2026-09-01). Data as JSON: /api/errors/c35e414fe087aed7. Report an issue: GitHub.