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
- 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.
- If the file is a different format, route it through the correct parser (MP4/MOV/MP3/WebM) or let parseMediaStream auto-detect.
- 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
- Let parseMediaStream auto-detect the container rather than forcing RIFF.
- Verify file extensions match content; a .wav is not always RIFF/WAVE.
- Sniff magic bytes before dispatching to a specific container parser.
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
- File type ${fileType} not supported
- Unsupported audio format ${strf.formatTag}
- Unsupported video codec ${strh.handler}
- Unsupported track type ${strh.fccType}
- Unsupported fccType: ${fccType}
AI-assisted analysis of remotion-dev/remotion@78fe4bb3fd (2026-08-12).
Data as JSON: /api/errors/c9b3aee4846f2235.
Report an issue: GitHub.