remotion-dev/remotion · warning · Error

Expected status code 200 or 404 for file, got ${file.status}

Error message

Expected status code 200 or 404 for file, got ${file.status}

What it means

To show an asset's size in the Studio Timeline/asset views, `getAssetMetadata()` issues `fetch(src, {method: 'HEAD'})` when the static-file listing has no `sizeInBytes` (always true for output files, packages/studio/src/helpers/get-asset-metadata.ts:66). It tolerates exactly 200 and 404; any other status (403, 401, 405, 500, ...) throws this error, which is caught and surfaced as a `metadata-error` result. It means the HTTP server behind the asset URL rejected the HEAD request.

Source

Thrown at packages/studio/src/helpers/get-asset-metadata.ts:133

		const listedStaticFile =
			canvasContent.type === 'asset'
				? window.remotion_staticFiles.find(
						(file) => file.name === canvasContent.asset && file.src === src,
					)
				: null;
		let size = listedStaticFile?.sizeInBytes ?? null;

		if (size === null) {
			const file = await fetch(src, {
				method: 'HEAD',
			});

			if (file.status === 404) {
				return {type: 'not-found'};
			}

			if (file.status !== 200) {
				throw new Error(
					`Expected status code 200 or 404 for file, got ${file.status}`,
				);
			}

			const contentLength = file.headers.get('content-length');

			if (!contentLength) {
				throw new Error('Unexpected error: content-length is null');
			}

			size = Number(contentLength);
		}

		const fetchedAt = Date.now();
		const srcWithTime = addTime ? addAssetCacheBust({fetchedAt, src}) : src;

		const fileType = getPreviewFileType(
			canvasContent.type === 'asset' ? canvasContent.asset : src,

View on GitHub (pinned to b2f4e34732)

Solutions

  1. Open the asset URL directly in a browser/curl and reproduce the status (`curl -I <src>`), then fix the server-side cause: refresh the signed URL, grant HEAD/read permission, or fix the failing route.
  2. Ensure the serving layer allows HEAD and returns 200 with the same behavior as GET.
  3. Prefer serving assets from the project `public/` folder so Studio's `remotion_staticFiles` listing already carries `sizeInBytes` and the HEAD request is skipped entirely.
  4. If it is an output file, verify the outputs route of the Studio server is healthy and the file finished writing.
Defensive patterns

Strategy: validation

Validate before calling

const verifyAssetHead = async (src: string): Promise<void> => {
  const res = await fetch(src, {method: 'HEAD'});
  if (res.status !== 200 && res.status !== 404) {
    throw new Error(`Asset server returned ${res.status} for HEAD ${src}`);
  }
};

// run before relying on Studio to display the asset's metadata

Prevention

When it happens

Trigger: A timeline asset (static file via `staticFile()` or a rendered output under `remotion_outputsBase`) whose URL returns a non-200/404 status to a HEAD request: expired or permission-denied signed URLs (403), auth-protected routes (401), servers/proxies that disallow HEAD (405), or backend errors (500/502).

Common situations: Assets on object storage (S3/R2) with expired signatures or missing HEAD permissions; CDN/auth proxies in front of the Studio that strip or block HEAD; broken output-serving routes in the dev server; assets added by path that no longer exist behind a redirecting proxy.

Understand the failure class

Related errors


AI-assisted analysis of remotion-dev/remotion@b2f4e34732 (2026-08-22). Data as JSON: /api/errors/9a28a0d5f7870f84. Report an issue: GitHub.