{"record":{"id":"8c2f6a584360c59b","repo":"remotion-dev/remotion","slug":"could-not-load-lut-http-response-status","errorCode":null,"errorMessage":"Could not load LUT (HTTP ${response.status}).","messagePattern":"Could not load LUT \\(HTTP (.+?)\\)\\.","errorType":"http","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/studio/src/components/LutPreview.tsx","lineNumber":177,"sourceCode":"\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tevent.preventDefault();\n\t\t\tevent.stopPropagation();\n\t\t},\n\t\t[],\n\t);\n\n\tuseEffect(() => {\n\t\tconst controller = new AbortController();\n\t\tconst image = new Image();\n\t\timage.crossOrigin = 'anonymous';\n\t\tsetState({type: 'loading'});\n\n\t\tconst load = async () => {\n\t\t\tconst response = await fetch(src, {signal: controller.signal});\n\t\t\tif (!response.ok) {\n\t\t\t\tthrow new Error(`Could not load LUT (HTTP ${response.status}).`);\n\t\t\t}\n\n\t\t\tconst lut = parseCubeLut(await response.text());\n\t\t\tif (controller.signal.aborted) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\timage.src = sampleImage;\n\t\t\ttry {\n\t\t\t\tawait image.decode();\n\t\t\t} catch {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t'Could not load the LUT sample image. Check your internet connection.',\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tif (controller.signal.aborted) {\n\t\t\t\treturn;","sourceCodeStart":159,"sourceCodeEnd":195,"githubUrl":"https://github.com/remotion-dev/remotion/blob/46a3a6bf13ca367376ff18bbb06dae2e87e0d068/packages/studio/src/components/LutPreview.tsx#L159-L195","documentation":"LutPreview fetches a .cube LUT file from a URL to render a before/after preview. When the HTTP response is not ok (4xx/5xx), it throws this error so the component can surface a load failure instead of silently rendering without the LUT.","triggerScenarios":"Passing a `src` prop URL to LutPreview that returns a non-2xx status: a 404 for a removed or mistyped LUT URL, a 403 from a bucket/CORS policy, or a 500 from the hosting server.","commonSituations":"LUT file moved or renamed on a CDN; S3/R2 bucket permissions changed; requesting a LUT through a proxy that blocks cross-origin anonymous fetches; offline or firewalled environment.","solutions":["Check the browser network tab for the failing LUT request status and URL; fix the URL or restore the file at that location.","Verify the host serves the .cube file with proper CORS headers since the fetch is cross-origin with an anonymous crossorigin image.","Test the LUT URL directly with curl to distinguish 404 (wrong URL) from 403 (permissions/CORS) from 5xx (server issue).","If the URL is user-supplied, validate it and show a fallback state in the UI."],"exampleFix":"// before\n<LutPreview src=\"https://cdn.example.com/luts/look1.cube\" />\n// after (verify the URL exists and is CORS-enabled first)\n<LutPreview src=\"https://cdn.example.com/luts/look-1-v2.cube\" />","handlingStrategy":"try-catch","validationCode":"const res = await fetch(lutUrl, {method: 'HEAD'});\nif (!res.ok) throw new Error(`LUT URL unavailable: ${res.status}`);","typeGuard":null,"tryCatchPattern":"try {\n  render(<LutPreview src={lutUrl} />);\n} catch (e) {\n  if (/Could not load LUT/.test(e.message)) showFallbackState();\n  else throw e;\n}","preventionTips":["Verify LUT URLs with a HEAD request before rendering the preview.","Serve .cube files with CORS headers from a stable CDN path.","Pin LUT assets to versioned URLs so they don't 404 after reorganization."],"tags":["network","http","fetch","lut"],"backgroundTag":"http-error-response","analyzedSha":"46a3a6bf13ca367376ff18bbb06dae2e87e0d068","analyzedAt":"2026-09-18T00:12:20.256Z","contentChangedAt":"2026-09-18T00:12:20.256Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}