{"record":{"id":"ba5b3482932876d6","repo":"remotion-dev/remotion","slug":"failed-to-upload-the-3d-lut-texture-webgl-error-uploaderror","errorCode":null,"errorMessage":"Failed to upload the 3D LUT texture (WebGL error ${uploadError})","messagePattern":"Failed to upload the 3D LUT texture \\(WebGL error (.+?)\\)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/effects/src/lut/lut-runtime.ts","lineNumber":202,"sourceCode":"\t\tgl.activeTexture(gl.TEXTURE1);\n\t\tgl.bindTexture(gl.TEXTURE_3D, lutTexture);\n\t\tgl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, false);\n\t\tgl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, false);\n\t\tgl.texImage3D(\n\t\t\tgl.TEXTURE_3D,\n\t\t\t0,\n\t\t\tgl.RGBA16F,\n\t\t\tparsed.size,\n\t\t\tparsed.size,\n\t\t\tparsed.size,\n\t\t\t0,\n\t\t\tgl.RGBA,\n\t\t\tgl.FLOAT,\n\t\t\tparsed.data,\n\t\t);\n\t\tconst uploadError = gl.getError();\n\t\tif (uploadError !== gl.NO_ERROR) {\n\t\t\tthrow new Error(\n\t\t\t\t`Failed to upload the 3D LUT texture (WebGL error ${uploadError})`,\n\t\t\t);\n\t\t}\n\n\t\tgl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, true);\n\t\tstate.cachedContent = content;\n\t}\n\n\tgl.viewport(0, 0, width, height);\n\tgl.bindFramebuffer(gl.FRAMEBUFFER, null);\n\tgl.clearColor(0, 0, 0, 0);\n\tgl.clear(gl.COLOR_BUFFER_BIT);\n\n\tgl.activeTexture(gl.TEXTURE0);\n\tgl.bindTexture(gl.TEXTURE_2D, sourceTexture);\n\tgl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, flipSourceY);\n\tgl.texImage2D(\n\t\tgl.TEXTURE_2D,","sourceCodeStart":184,"sourceCodeEnd":220,"githubUrl":"https://github.com/remotion-dev/remotion/blob/46a3a6bf13ca367376ff18bbb06dae2e87e0d068/packages/effects/src/lut/lut-runtime.ts#L184-L220","documentation":"After uploading the parsed LUT data with gl.texImage3D(..., gl.FLOAT, parsed.data), applyLut() polls gl.getError(). Any value other than gl.NO_ERROR means the GPU rejected the 3D texture upload, and the library throws with the raw WebGL error enum in the message. Unlike the size check ([25]), this catches failures at the actual upload (out-of-memory, invalid data, driver limits).","triggerScenarios":"texImage3D fails with GL errors such as OUT_OF_MEMORY (LUT too large for GPU memory), INVALID_VALUE (malformed data length vs LUT_3D_SIZE^3), or driver-specific float-texture restrictions; also fires after context loss.","commonSituations":"Oversized LUTs on memory-constrained mobile GPUs; .cube files whose declared size doesn't match the number of data rows; browsers/GPUs with poor float (RGBA32F) texture support; context lost between texture creation and upload.","solutions":["Decode the numeric error in the message: 0x505 (OUT_OF_MEMORY) means the LUT is too big - use a smaller LUT_3D_SIZE","Verify the .cube data row count matches LUT_3D_SIZE^3 (a mismatched file produces INVALID_VALUE)","Reduce LUT size (e.g. 33 -> 17) to lower memory requirements","Check gl.isContextLost(); if lost, recreate the context and re-run setupLut","Update GPU drivers/browser if float-texture upload fails on a known-good LUT"],"exampleFix":"// before: oversized LUT on mobile\nconst lut = parseCubeLut(lutSize64File);\napplyLut(state, lut);\n// after: fall back to a smaller resampled LUT\nconst lut = parseCubeLut(lutSize64File);\nconst safe = state.gl.getParameter(state.gl.MAX_3D_TEXTURE_SIZE) < 64\n  ? downsampleCubeLut(lut, 32)\n  : lut;\napplyLut(state, safe);","handlingStrategy":"try-catch","validationCode":"const expected = size * size * size * 4;\nif (parsed.data.length !== expected) {\n  throw new Error(`LUT data length ${parsed.data.length} != ${expected}`);\n}","typeGuard":null,"tryCatchPattern":"try {\n  applyLut(state, content);\n} catch (e) {\n  if (e.message.startsWith('Failed to upload the 3D LUT texture')) {\n    // decode WebGL error enum in message; on OUT_OF_MEMORY use a smaller LUT,\n    // if gl.isContextLost() recreate the context and setupLut again\n  }\n}","preventionTips":["Ensure .cube data row count matches LUT_3D_SIZE^3 exactly","Use smaller LUT sizes on memory-constrained devices","Check context loss before uploading","Avoid oversized 64+ LUTs on mobile; resample to 32"],"tags":["webgl","texture-upload","out-of-memory","lut"],"backgroundTag":"module-init-failed","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"}