{"record":{"id":"f53d269308ee4376","repo":"remotion-dev/remotion","slug":"timed-out-downloading-remote-asset","errorCode":null,"errorMessage":"Timed out downloading remote asset","messagePattern":"Timed out downloading remote asset","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/browser-studio/src/download-remote-asset.ts","lineNumber":60,"sourceCode":"\t\tthrow new Error('Remote asset URLs cannot include credentials');\n\t}\n\n\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}","sourceCodeStart":42,"sourceCodeEnd":78,"githubUrl":"https://github.com/remotion-dev/remotion/blob/10db9de07356446fb0edb3c3ae211369b693d18b/packages/browser-studio/src/download-remote-asset.ts#L42-L78","documentation":"Thrown by downloadRemoteAsset in @remotion/browser-studio when the fetch is aborted by the built-in timeout (remoteAssetDownloadTimeout via AbortController) — the asset server did not respond within the allowed window, either for the initial response or while streaming the body. The AbortError is translated to this message; the promise rejects directly.","triggerScenarios":"Importing a large image from a slow or distant server; server stalls mid-download (the body-streaming loop is also covered by the same timeout); client network degraded (offline, throttled); server takes long to generate the asset on the fly.","commonSituations":"Users on slow connections importing multi-megapixel images; origin servers behind slow CDN cold starts; mobile networks; localhost dev with a stalled mock server.","solutions":["Retry the import — transient timeouts often succeed on a second attempt","Host the asset on a faster CDN closer to the user, or pre-compress/resize it","Check the URL opens quickly in a browser tab on the same network","If it consistently times out, download the asset manually and add it via writeStaticFile"],"exampleFix":"// before\nawait operations.downloadRemoteAsset({url}); // may reject: Timed out downloading remote asset\n\n// after\nasync function importWithRetry(url: string, attempts = 2) {\n  for (let i = 0; i <= attempts; i++) {\n    try {\n      return await operations.downloadRemoteAsset({url});\n    } catch (e) {\n      const isTimeout = e instanceof Error && e.message === 'Timed out downloading remote asset';\n      if (!isTimeout || i === attempts) throw e;\n    }\n  }\n  throw new Error('unreachable');\n}","handlingStrategy":"retry","validationCode":"const reachable = await fetch(url, {method: 'HEAD', signal: AbortSignal.timeout(5000)}).then((r) => r.ok).catch(() => false);\nif (!reachable) throw new Error('Asset server not responding — try again later');","typeGuard":null,"tryCatchPattern":"const isTimeout = (e: unknown) => e instanceof Error && e.message === 'Timed out downloading remote asset';\ntry {\n  result = await operations.downloadRemoteAsset({url});\n} catch (error) {\n  if (isTimeout(error) && attempt < maxAttempts) { await backoff(attempt); return download(attempt + 1); }\n  throw error;\n}","preventionTips":["Retry once or twice with backoff — timeouts are frequently transient","Import from CDNs with low latency to your users","Pre-compress oversized or slow assets instead of importing originals"],"tags":["network","timeout","asset-import","browser-studio"],"backgroundTag":"download-timeout","analyzedSha":"10db9de07356446fb0edb3c3ae211369b693d18b","analyzedAt":"2026-08-22T21:45:17.748Z","schemaVersion":2},"datasetVersion":"2026-08-31T19:17:28.585Z"}