remotion-dev/remotion · error · Error

Unexpected end of file

Error message

Unexpected end of file

What it means

Thrown by parseM3uManifest() at parse-m3u-manifest.ts:18 when, after reading a line via iterator.readUntilLineEnd(), the iterator's byte offset exceeds the declared contentLength. This means the byte stream ended mid-line — the manifest data was truncated or contentLength was set to a value smaller than the actual data read.

Source

Thrown at packages/media-parser/src/containers/m3u/parse-m3u-manifest.ts:18

import type {BufferIterator} from '../../iterator/buffer-iterator';
import type {ParseResult} from '../../parse-result';
import {parseM3u8Text} from './parse-m3u8-text';
import type {M3uStructure} from './types';

export const parseM3uManifest = ({
	iterator,
	structure,
	contentLength,
}: {
	iterator: BufferIterator;
	structure: M3uStructure;
	contentLength: number;
}): Promise<ParseResult> => {
	const start = iterator.startCheckpoint();
	const line = iterator.readUntilLineEnd();
	if (iterator.counter.getOffset() > contentLength) {
		throw new Error('Unexpected end of file');
	}

	if (line === null) {
		start.returnToCheckpoint();
		return Promise.resolve(null);
	}

	parseM3u8Text(line.trim(), structure.boxes);

	return Promise.resolve(null);
};

View on GitHub (pinned to 78fe4bb3fd)

Solutions

  1. Retry the fetch to rule out transient network truncation
  2. Verify the Content-Length header matches the actual response body size
  3. Check for intermediate proxies or load balancers that may truncate large responses
Defensive patterns

Strategy: retry

Validate before calling

// Verify the response is complete before parsing
const resp = await fetch(url);
const text = await resp.text();
if (text.trim() === '' || !resp.ok) {
  throw new Error('Manifest response is empty or failed');
}
const contentLength = Number(resp.headers.get('content-length') ?? text.length);
if (text.length < contentLength) {
  throw new Error('Manifest response was truncated');
}
await parseMedia({src: url});

Try / catch

async function parseWithRetry(src: string, retries = 3) {
  for (let i = 0; i <= retries; i++) {
    try {
      return await parseMedia({src});
    } catch (e) {
      if (e instanceof Error && e.message === 'Unexpected end of file' && i < retries) continue;
      throw e;
    }
  }
}

Prevention

When it happens

Trigger: The HTTP response body was cut short (connection dropped, proxy timeout, partial cache); contentLength was computed incorrectly (e.g., from a wrong Content-Length header); or the reader returned fewer bytes than expected but the iterator advanced past the boundary.

Common situations: Network timeout during manifest download; CDN or reverse proxy truncating large manifests; incorrect Content-Length header from the origin server; file read interrupted by process abort.

Related errors


AI-assisted analysis of remotion-dev/remotion@78fe4bb3fd (2026-08-12). Data as JSON: /api/errors/60203ce511a11185. Report an issue: GitHub.