bilibili/flv.js · error · RuntimeException
Fetch stream meet Early-EOF
Error message
Fetch stream meet Early-EOF
What it means
FetchStreamLoader's internal _pump loop reads the fetch body via reader.read(); when the stream ends before the expected content-length has been received, it treats it as a premature connection termination. The loader sets status to kError and fires _onError with LoaderErrors.EARLY_EOF (code -1), or throws a RuntimeException if no error callback was registered. This means the server (or a proxy) closed the connection mid-download.
Source
Thrown at src/io/fetch-stream-loader.js:199
this._abortController.abort();
} catch (e) {}
}
}
}
_pump(reader) { // ReadableStreamReader
return reader.read().then((result) => {
if (result.done) {
// First check received length
if (this._contentLength !== null && this._receivedLength < this._contentLength) {
// Report Early-EOF
this._status = LoaderStatus.kError;
let type = LoaderErrors.EARLY_EOF;
let info = {code: -1, msg: 'Fetch stream meet Early-EOF'};
if (this._onError) {
this._onError(type, info);
} else {
throw new RuntimeException(info.msg);
}
} else {
// OK. Download complete
this._status = LoaderStatus.kComplete;
if (this._onComplete) {
this._onComplete(this._range.from, this._range.from + this._receivedLength - 1);
}
}
} else {
if (this._abortController && this._abortController.signal.aborted) {
this._status = LoaderStatus.kComplete;
return;
} else if (this._requestAbort === true) {
this._status = LoaderStatus.kComplete;
return reader.cancel();
}
this._status = LoaderStatus.kBuffering;View on GitHub (pinned to 42343088f2)
Solutions
- Add an onError handler to the loader (or listen for the player's LOAD_ERROR/NetworkError) and implement a retry that re-opens the stream from the last received byte offset using a Range request
- Verify no intermediary (proxy/CDN/load balancer) has an idle/timeout limit shorter than the download duration and raise it
- Confirm the server sends a correct Content-Length or use chunked transfer encoding consistently
- Switch loader type (e.g. to RangeLoader/XHR-based loader) via config for flaky networks
Example fix
// before
loader.create(url, { from: 0, to: -1 }); // no error handling; throws RuntimeException
// after
loader._onError = (type, info) => {
if (type === LoaderErrors.EARLY_EOF) {
// resume from last received offset with a Range request
loader.create(url, { from: loader._receivedLength, to: -1 });
}
};
loader.create(url, { from: 0, to: -1 }); Defensive patterns
Strategy: retry
Validate before calling
const res = await fetch(url);
if (!res.ok || !res.body) throw new Error('bad response');
const len = Number(res.headers.get('content-length'));
if (Number.isNaN(len)) console.warn('no content-length; EOF detection limited'); Try / catch
loader._onError = (type, info) => {
if (type === LoaderErrors.EARLY_EOF) {
setTimeout(() => loader.create(url, { from: lastReceivedOffset, to: -1 }), backoffMs);
}
}; Prevention
- Always register an onError callback so EARLY_EOF becomes recoverable
- Track received byte offset so retries can resume via Range requests
- Raise proxy/CDN idle timeouts for long media transfers
- Monitor server Content-Length correctness
When it happens
Trigger: Calling create() on a FetchStreamLoader and, during streaming, the response body ReadableStream ends while _receivedLength < _contentLength; typically response.headers content-length was advertised but the connection dropped before that many bytes arrived. Also raised when res.body is null/unreadable mid-pump or the reader's done flag arrives early.
Common situations: Unstable mobile networks, proxy/CDN idle timeouts (nginx, Cloudflare) cutting long streaming responses, server crashes or restarts mid-transfer, load balancers killing slow connections, or servers that send an incorrect Content-Length header.
Related errors
- FetchStreamLoader: Http code invalid, ' + res.status + ' ' +
- IOException: ' + data.msg
- MozChunkedLoader: Http code invalid, ' + xhr.status + ' ' +
- MSStreamLoader: Http code invalid, ' + xhr.status + ' ' + xh
- RangeLoader: Http code invalid, ' + xhr.status + ' ' + xhr.s
AI-assisted analysis of bilibili/flv.js@42343088f2 (2026-09-01).
Data as JSON: /api/errors/764fb4475e8e853a.
Report an issue: GitHub.