remotion-dev/remotion · error · Error

Failed to fetch audio data from ${src}: ${response.status} $

Error message

Failed to fetch audio data from ${src}: ${response.status} ${response.statusText}

What it means

Thrown by getAudioData() when the underlying fetch() of the audio src returns a non-2xx response (line 32-35). The message embeds the request URL, HTTP status, and statusText so you can see exactly what the server rejected. It is a hard failure: the function cannot decode audio data it never received.

Source

Thrown at packages/media-utils/src/get-audio-data.ts:33

const fn = async (
	src: string,
	options?: Options,
): Promise<MediaUtilsAudioData> => {
	if (metadataCache[src]) {
		return metadataCache[src];
	}

	if (typeof document === 'undefined') {
		throw new Error('getAudioData() is only available in the browser.');
	}

	const audioContext = new AudioContext({
		sampleRate: options?.sampleRate ?? 48000,
	});

	const response = await fetchWithCorsCatch(src, options?.requestInit);
	if (!response.ok) {
		throw new Error(
			`Failed to fetch audio data from ${src}: ${response.status} ${response.statusText}`,
		);
	}

	const arrayBuffer = await response.arrayBuffer();

	const wave = await audioContext.decodeAudioData(arrayBuffer);

	const channelWaveforms = new Array(wave.numberOfChannels)
		.fill(true)
		.map((_, channel) => {
			return wave.getChannelData(channel);
		});

	const metadata: MediaUtilsAudioData = {
		channelWaveforms,
		sampleRate: wave.sampleRate,
		durationInSeconds: wave.duration,

View on GitHub (pinned to 78fe4bb3fd)

Solutions

  1. Open the exact URL printed in the message in a browser/Postman and confirm it returns 200 with an audio MIME type.
  2. For local assets in Remotion, pass staticFile('audio.mp3') and place the file under public/, never a raw '/public/...' path.
  3. For remote assets, verify the signed URL has not expired and re-issue it; pass {requestInit: {credentials: 'include'}} if cookies/auth are required.
  4. Check server CORS headers: the response needs Access-Control-Allow-Origin matching your origin (or use a CORS proxy). The fetchWithCorsCatch wrapper usually throws a different CORS message first, so a plain status error means the host itself rejected the request.
  5. Confirm the asset host is reachable from the browser tab running Remotion (firewall, VPN, localhost vs 0.0.0.0).

Example fix

// before (relative path Studio cannot resolve -> 404)
const data = await getAudioData('/public/song.mp3');

// after (resolve through Remotion's static file server)
import {staticFile} from 'remotion';
const data = await getAudioData(staticFile('song.mp3'));
Defensive patterns

Strategy: try-catch

Validate before calling

// Verify the URL is reachable with the expected status before decoding
async function assertAudioReachable(src: string, requestInit?: RequestInit) {
  const res = await fetch(src, {method: 'GET', ...requestInit});
  if (!res.ok) {
    throw new Error(`Audio URL ${src} returned ${res.status} ${res.statusText}`);
  }
  const type = res.headers.get('content-type') ?? '';
  if (!type.startsWith('audio/') && !type.startsWith('video/') && type !== 'application/octet-stream') {
    console.warn(`Unexpected content-type ${type} for ${src}`);
  }
}

Type guard

const isHttpOk = (status: number): boolean => status >= 200 && status < 300;

Try / catch

try {
  const data = await getAudioData(src, {requestInit});
} catch (err) {
  const msg = (err as Error).message;
  if (msg.startsWith('Failed to fetch audio data')) {
    // surface the URL/status, log, and decide on a fallback (skip visualization)
    console.error('Audio fetch failed:', msg);
    return null;
  }
  throw err;
}

Prevention

When it happens

Trigger: Passing a 404 audio URL; an expired/expired-signed S3 or CloudFront URL; a relative path that 404s under Studio because staticFile() was not used; CORS preflight returning 403; a remote URL behind auth without credentials; calling before the dev/static server is up.

Common situations: Hard-coded URL that works locally but 404s in production; forgetting staticFile() and passing a bare '/public/audio.mp3' that Studio can't resolve; CDN/signed URL expired between fetch and decode; remote audio behind Cloudflare hotlink protection returning 403; wrong file extension casing on case-sensitive hosts.

Related errors


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