{"record":{"id":"7de214aac9581ac1","repo":"remotion-dev/remotion","slug":"http-error-status-res-status","errorCode":null,"errorMessage":"HTTP error, status = ${res.status}","messagePattern":"HTTP error, status = (.+?)","errorType":"http","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/core/src/prefetch.ts","lineNumber":163,"sourceCode":"\t\tresolve = res;\n\t\treject = rej;\n\t});\n\twaitUntilDone.catch(() => undefined);\n\n\tconst controller = new AbortController();\n\tlet reader: ReadableStreamDefaultReader<Uint8Array> | null = null;\n\n\tfetch(srcWithoutHash, {\n\t\tsignal: controller.signal,\n\t\tcredentials: options?.credentials ?? undefined,\n\t})\n\t\t.then((res) => {\n\t\t\tif (canceled) {\n\t\t\t\treturn null;\n\t\t\t}\n\n\t\t\tif (!res.ok) {\n\t\t\t\tthrow new Error(`HTTP error, status = ${res.status}`);\n\t\t\t}\n\n\t\t\tconst headerContentType = res.headers.get('Content-Type');\n\n\t\t\tconst contentType = options?.contentType ?? headerContentType;\n\t\t\tconst hasProperContentType =\n\t\t\t\tcontentType &&\n\t\t\t\t(contentType.startsWith('video/') ||\n\t\t\t\t\tcontentType.startsWith('audio/') ||\n\t\t\t\t\tcontentType.startsWith('image/'));\n\n\t\t\tif (!hasProperContentType) {\n\t\t\t\t// eslint-disable-next-line no-console\n\t\t\t\tconsole.warn(\n\t\t\t\t\t`Called prefetch() on ${srcWithoutHash} which returned a \"Content-Type\" of ${headerContentType}. Prefetched content should have a proper content type (video/... or audio/...) or a contentType passed the options of prefetch(). Otherwise, prefetching will not work properly in all browsers.`,\n\t\t\t\t);\n\t\t\t}\n","sourceCodeStart":145,"sourceCodeEnd":181,"githubUrl":"https://github.com/remotion-dev/remotion/blob/78fe4bb3fdb5a2cd68724393d63cb223db333fa7/packages/core/src/prefetch.ts#L145-L181","documentation":"prefetch() fetches a media URL to warm the browser cache before playback. After fetch() resolves it checks `res.ok`; any non-2xx HTTP status throws with the numeric status code. This surfaces network/server problems immediately rather than letting playback fail silently later.","triggerScenarios":"404 for a missing asset, 403 forbidden, 500 server error, CORS preflight rejection, expired signed URL, wrong/typo path.","commonSituations":"Public-folder path typo; asset not deployed; dev server not running; signed/expired CDN URL; cross-origin without CORS headers.","solutions":["Open the URL directly in a browser to confirm it returns 2xx.","Verify the path resolves (use staticDirectory()/publicFolder helpers correctly).","Ensure the dev/preview server is running and serving the file.","If cross-origin, confirm the server sends Access-Control-Allow-Origin and survives the CORS preflight."],"exampleFix":null,"handlingStrategy":"retry","validationCode":"async function assertOk(url: string) {\n  const res = await fetch(url, { method: 'HEAD' });\n  if (!res.ok) throw new Error(`prefetch will fail: ${res.status}`);\n}","typeGuard":null,"tryCatchPattern":"try {\n  await prefetch(src);\n} catch (err) {\n  if (/HTTP error, status =/.test(String(err))) {\n    // log + fall back to direct src, or surface to the user\n  } else throw err;\n}","preventionTips":["Verify media URLs return 2xx before passing to prefetch().","Use staticDirectory()/publicFolder helpers to build correct paths.","Confirm CORS headers for cross-origin assets.","Add a retry wrapper for transient 5xx responses."],"tags":["network","prefetch","http","media"],"backgroundTag":null,"analyzedSha":"78fe4bb3fdb5a2cd68724393d63cb223db333fa7","analyzedAt":"2026-08-12T17:18:50.444Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}