remotion-dev/remotion · error · Error

Could not determine duration of ${src}, but "loop" was set.

Error message

Could not determine duration of ${src}, but "loop" was set.

What it means

Thrown by getTimeInSeconds in @remotion/media when `loop` is true, the media duration could not be determined (null), and the caller requested 'fail' behavior for missing duration. Looping requires knowing the media length to wrap the playhead, so an unknown duration makes looping mathematically impossible. Fires at get-time-in-seconds.ts:25.

Source

Thrown at packages/media/src/get-time-in-seconds.ts:25

	src,
	trimAfter,
	trimBefore,
	fps,
	playbackRate,
	ifNoMediaDuration,
}: {
	loop: boolean;
	mediaDurationInSeconds: number | null;
	unloopedTimeInSeconds: number;
	src: string;
	trimAfter: number | undefined;
	trimBefore: number | undefined;
	playbackRate: number;
	fps: number;
	ifNoMediaDuration: 'fail' | 'infinity';
}) => {
	if (mediaDurationInSeconds === null && loop && ifNoMediaDuration === 'fail') {
		throw new Error(
			`Could not determine duration of ${src}, but "loop" was set.`,
		);
	}

	const loopDurationInFrames = loop
		? Internals.calculateMediaDuration({
				trimAfter,
				mediaDurationInFrames: mediaDurationInSeconds
					? mediaDurationInSeconds * fps
					: Infinity,
				// Playback rate was already specified before
				playbackRate: 1,
				trimBefore,
			})
		: Infinity;

	const timeInSeconds = loop
		? ((unloopedTimeInSeconds * playbackRate * fps) % loopDurationInFrames) /

View on GitHub (pinned to 78fe4bb3fd)

Solutions

  1. Remove the loop prop if you do not strictly need looping.
  2. Repair or re-encode the source so its duration metadata is present: ffmpeg -i broken.mp4 -c copy fixed.mp4.
  3. Use a well-formed MP4/WebM whose duration is readable by ffprobe.

Example fix

// before
<Video src={staticFile('clip.mp4')} loop /> // clip.mp4 has no duration metadata

// after
<Video src={staticFile('clip.mp4')} /> // no loop, or re-encode the file first
Defensive patterns

Strategy: validation

Validate before calling

null

Try / catch

// Avoid by ensuring duration is readable; if loop is optional, gate it:
const canLoop = mediaDuration != null;
<Video src={src} loop={canLoop && userWantsLoop} />;

Prevention

When it happens

Trigger: Setting loop on a <Video>/<Audio>/<OffthreadVideo> whose duration metadata cannot be read (corrupt header, truncated file, unsupported container), while ifNoMediaDuration is set to 'fail'. The duration probe returns null and loop is true.

Common situations: A media file with missing or malformed duration metadata (broken MP4 header, incomplete download), a container Remotion cannot fully parse, or a remote URL that returned partial data. Looping amplifies the requirement for duration.

Related errors


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