{"record":{"id":"c5fe5ba8ec3f698f","repo":"remotion-dev/remotion","slug":"could-not-download-remote-asset-response-status","errorCode":null,"errorMessage":"Could not download remote asset: ${response.status}","messagePattern":"Could not download remote asset: (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/browser-studio/src/download-remote-asset.ts","lineNumber":71,"sourceCode":"\t\ttry {\n\t\t\tresponse = await fetch(url, {\n\t\t\t\theaders: {accept: remoteAssetAcceptHeader},\n\t\t\t\tsignal: abortController.signal,\n\t\t\t});\n\t\t} catch (error) {\n\t\t\tif (error instanceof Error && error.name === 'AbortError') {\n\t\t\t\tthrow new Error('Timed out downloading remote asset');\n\t\t\t}\n\n\t\t\tthrow new Error(\n\t\t\t\t`Could not fetch remote asset. The URL may not allow cross-origin requests (CORS): ${\n\t\t\t\t\terror instanceof Error ? error.message : String(error)\n\t\t\t\t}`,\n\t\t\t);\n\t\t}\n\n\t\tif (!response.ok) {\n\t\t\tthrow new Error(`Could not download remote asset: ${response.status}`);\n\t\t}\n\n\t\tconst contentLength = response.headers.get('content-length');\n\t\tif (contentLength !== null && Number(contentLength) > maxRemoteAssetSize) {\n\t\t\tabortController.abort();\n\t\t\tthrow new Error('Remote asset exceeds the 50MB size limit');\n\t\t}\n\n\t\tif (!response.body) {\n\t\t\tconst buffer = await response.arrayBuffer();\n\t\t\tif (buffer.byteLength > maxRemoteAssetSize) {\n\t\t\t\tthrow new Error('Remote asset exceeds the 50MB size limit');\n\t\t\t}\n\n\t\t\tcontents = new Uint8Array(buffer);\n\t\t} else {\n\t\t\tconst reader = response.body.getReader();\n\t\t\tconst chunks: Uint8Array[] = [];","sourceCodeStart":53,"sourceCodeEnd":89,"githubUrl":"https://github.com/remotion-dev/remotion/blob/10db9de07356446fb0edb3c3ae211369b693d18b/packages/browser-studio/src/download-remote-asset.ts#L53-L89","documentation":"Thrown by downloadRemoteAsset in @remotion/browser-studio when the fetch completed but `response.ok` is false — the server answered with an HTTP error status (404, 403, 500, ...). The status code is included in the message. The promise rejects directly, so callers must catch it.","triggerScenarios":"Calling `downloadRemoteAsset({url})` for a deleted/expired link (404), a signed URL past its expiry or with a bad signature (403), a rate-limited or broken origin (429/5xx), or a URL that returns HTML error pages instead of an image.","commonSituations":"Pasted links from expiring share URLs; hotlink-protected hosts; CDN URLs that require a token; typos in paths.","solutions":["Open the URL directly in a browser tab and confirm it returns the image with a 200","For 403/410 on signed URLs, generate a fresh signed URL and retry","For 404, fix the path — the asset moved or was deleted","For 5xx/429, wait and retry later or mirror the asset to a reliable host"],"exampleFix":"// before\nawait operations.downloadRemoteAsset({url}); // rejects: Could not download remote asset: 404\n\n// after\ntry {\n  await operations.downloadRemoteAsset({url});\n} catch (e) {\n  const m = e instanceof Error && e.message.match(/Could not download remote asset: (\\d+)/);\n  if (m) {\n    const status = Number(m[1]);\n    if (status === 404) throw new Error('That link no longer exists — check the URL');\n    if (status === 403) throw new Error('The host denied access — the link may have expired');\n  }\n  throw e;\n}","handlingStrategy":"try-catch","validationCode":"const check = await fetch(url, {method: 'HEAD'});\nif (!check.ok) throw new Error(`Asset URL returned ${check.status}`);","typeGuard":null,"tryCatchPattern":"try {\n  await operations.downloadRemoteAsset({url});\n} catch (error) {\n  const m = error instanceof Error ? error.message.match(/Could not download remote asset: (\\d+)/) : null;\n  if (m) {\n    const status = Number(m[1]);\n    if (status === 404 || status === 410) throw new Error('Link is dead — the asset was moved or deleted');\n    if (status === 403) throw new Error('Access denied — the link may be expired or signed incorrectly');\n    throw new Error(`Origin server error (${status}) — try again later`);\n  }\n  throw error;\n}","preventionTips":["Validate pasted links with a HEAD request before adding them to a project","Regenerate signed URLs at import time rather than persisting them","For 5xx/429 responses, back off before retrying"],"tags":["network","http-status","asset-import","browser-studio"],"backgroundTag":"http-error-status","analyzedSha":"10db9de07356446fb0edb3c3ae211369b693d18b","analyzedAt":"2026-08-22T21:45:17.748Z","schemaVersion":2},"datasetVersion":"2026-08-31T19:17:28.585Z"}