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
- Open the exact URL printed in the message in a browser/Postman and confirm it returns 200 with an audio MIME type.
- For local assets in Remotion, pass staticFile('audio.mp3') and place the file under public/, never a raw '/public/...' path.
- For remote assets, verify the signed URL has not expired and re-issue it; pass {requestInit: {credentials: 'include'}} if cookies/auth are required.
- 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.
- 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
- For local assets always use staticFile() so Remotion serves the correct URL.
- For remote/signed URLs, refresh the signature close to use time; do not cache it long-term.
- Add a quick HEAD/GET check in dev to confirm the URL returns 2xx and an audio MIME type.
- Make sure CORS headers on the host allow your Studio origin before relying on cross-origin fetch.
- Use absolute https URLs in production; avoid protocol-relative or hardcoded http URLs behind https pages.
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
- Failed to render GIF with source ${src}: "${error.message}".
- Failed to render GIF with source ${src}: "${error.message}".
- Failed to read from ${src}: ${error.message}. Does the resou
- Got no body
- HTTP error, status = ${res.status}
AI-assisted analysis of remotion-dev/remotion@78fe4bb3fd (2026-08-12).
Data as JSON: /api/errors/130243da1470de28.
Report an issue: GitHub.