remotion-dev/remotion · error

Not a RIFF file

Error message

Not a RIFF file

What it means

Thrown by parseRiffHeader() when the first 4 bytes of the stream are not the ASCII bytes 'RIFF'. This is the container-format sniff for RIFF (used by WAV and AVI); a mismatch means the data is not a RIFF container, but the parser was dispatched to the RIFF path anyway.

Source

Thrown at packages/media-parser/src/containers/riff/parse-riff-header.ts:7

import type {ParseResult} from '../../parse-result';
import type {ParserState} from '../../state/parser-state';

export const parseRiffHeader = (state: ParserState): ParseResult => {
	const riff = state.iterator.getByteString(4, false);
	if (riff !== 'RIFF') {
		throw new Error('Not a RIFF file');
	}

	const structure = state.structure.getRiffStructure();

	const size = state.iterator.getUint32Le();
	const fileType = state.iterator.getByteString(4, false);
	if (fileType !== 'WAVE' && fileType !== 'AVI') {
		throw new Error(`File type ${fileType} not supported`);
	}

	structure.boxes.push({type: 'riff-header', fileSize: size, fileType});

	return null;
};

View on GitHub (pinned to 78fe4bb3fd)

Solutions

  1. Verify the file is actually a RIFF container: check the first 4 bytes equal 0x52 0x49 0x46 0x46 ('RIFF') before parsing, or run ffmpeg -i to inspect.
  2. If the file is a different format, route it through the correct parser (MP4/MOV/MP3/WebM) or let parseMediaStream auto-detect.
  3. Re-export the asset from its source as a real WAV/AVI if it is supposed to be RIFF.

Example fix

// before
await parseMediaStream({src: maybeWavUrl, ...});

// after
const head = new Uint8Array(await (await fetch(maybeWavUrl, {headers: {Range: 'bytes=0-3'}})).arrayBuffer());
const isRiff = head[0] === 0x52 && head[1] === 0x49 && head[2] === 0x46 && head[3] === 0x46;
if (!isRiff) throw new Error('Not a WAV/AVI');
Defensive patterns

Strategy: validation

Validate before calling

// Sniff the first 4 bytes for 'RIFF' before parsing.
const head = new Uint8Array(await (await fetch(url, {headers: {Range: 'bytes=0-3'}})).arrayBuffer());
const isRiff = head[0] === 0x52 && head[1] === 0x49 && head[2] === 0x46 && head[3] === 0x46;
if (!isRiff) throw new Error('Not a RIFF container');

Type guard

function isRiffMagic(bytes: Uint8Array): boolean {
  return bytes.length >= 4 && bytes[0] === 0x52 && bytes[1] === 0x49 && bytes[2] === 0x46 && bytes[3] === 0x46;
}

Try / catch

try {
  await parseMediaStream({src: url});
} catch (err) {
  if (err instanceof Error && err.message === 'Not a RIFF file') {
    // route to the correct container parser or auto-detect
  } else throw err;
}

Prevention

When it happens

Trigger: The parser's container detection routed a non-RIFF file to parseRiffHeader, or the file is genuinely not WAV/AVI. Also fires on truncated/empty input where fewer than 4 bytes are available (the byte-string read returns something other than 'RIFF').

Common situations: Wrong file extension (e.g. .wav on an MP3); corrupt or empty file; misconfigured container detection that preferred RIFF over the real format.

Related errors


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