{"record":{"id":"9353670d55674434","repo":"remotion-dev/remotion","slug":"could-not-fetch-remote-asset-the-url-may-not-allo","errorCode":null,"errorMessage":"Could not fetch remote asset. The URL may not allow cross-origin requests (CORS): ${error instanceof Error ? error.message : String(error)}","messagePattern":"Could not fetch remote asset\\. The URL may not allow cross-origin requests \\(CORS\\): (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/browser-studio/src/download-remote-asset.ts","lineNumber":63,"sourceCode":"\tconst abortController = new AbortController();\n\tconst timeout = setTimeout(() => {\n\t\tabortController.abort();\n\t}, remoteAssetDownloadTimeout);\n\n\tlet contents: Uint8Array;\n\ttry {\n\t\tlet response: Response;\n\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();","sourceCodeStart":45,"sourceCodeEnd":81,"githubUrl":"https://github.com/remotion-dev/remotion/blob/10db9de07356446fb0edb3c3ae211369b693d18b/packages/browser-studio/src/download-remote-asset.ts#L45-L81","documentation":"Thrown by downloadRemoteAsset in @remotion/browser-studio when the underlying fetch throws for a non-timeout reason. In a browser this is most often a CORS failure — the asset host did not send Access-Control-Allow-Origin for your page's origin — but it also covers DNS failures, refused connections, and offline errors, which is why the raw browser message is appended. The promise rejects directly.","triggerScenarios":"Calling `downloadRemoteAsset({url})` where the host lacks CORS headers for the Studio's origin; mixed-content (https page importing http:// asset); DNS does not resolve; browser offline. The fetch fails before a Response exists, distinguishing it from HTTP status errors.","commonSituations":"Pasting image links from random sites (most don't allow cross-origin fetch); importing from internal hostnames not reachable from the user's machine; http:// URLs inside an https:// embedded Studio.","solutions":["Verify the URL returns the image when opened directly in a tab, then confirm the host sends `Access-Control-Allow-Origin` for your origin (curl -I and look for the header)","Serve the asset from a CORS-enabled host or your own CDN/proxy that adds the header","If the asset is already reachable elsewhere, download it and add via writeStaticFile instead","Catch the rejection and show the user that the site does not permit cross-origin imports"],"exampleFix":"// before\nawait operations.downloadRemoteAsset({url}); // rejects: ...may not allow cross-origin requests (CORS)\n\n// after\ntry {\n  await operations.downloadRemoteAsset({url});\n} catch (e) {\n  if (e instanceof Error && e.message.includes('cross-origin')) {\n    alert('That site blocks cross-origin downloads. Save the image and upload it instead.');\n  } else {\n    throw e;\n  }\n}","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n  await operations.downloadRemoteAsset({url});\n} catch (error) {\n  if (error instanceof Error && error.message.includes('cross-origin requests (CORS)')) {\n    showUserMessage('That site does not allow cross-origin downloads. Save the image and upload it instead.');\n    return;\n  }\n  throw error;\n}","preventionTips":["Restrict import UIs to known CORS-enabled hosts (your CDN, major image hosts)","Offer a file-upload fallback whenever URL import fails","Avoid http:// asset URLs inside https-hosted Studios (mixed content fails the same way)"],"tags":["network","cors","fetch","asset-import","browser-studio"],"backgroundTag":"cors-request-blocked","analyzedSha":"10db9de07356446fb0edb3c3ae211369b693d18b","analyzedAt":"2026-08-22T21:45:17.748Z","schemaVersion":2},"datasetVersion":"2026-08-31T19:17:28.585Z"}