{"record":{"id":"b523d7d2715d6c88","repo":"gitroomhq/postiz-app","slug":"file-is-too-large","errorCode":null,"errorMessage":"File is too large.","messagePattern":"File is too large\\.","errorType":"http","errorClass":"HttpException","httpStatus":400,"severity":"error","filePath":"apps/backend/src/public-api/routes/v1/public.integrations.controller.ts","lineNumber":133,"sourceCode":"        dispatcher: ssrfSafeDispatcher,\n      });\n    } catch {\n      // Network-level failure (DNS, connection refused, SSRF block, etc.) —\n      // fetch rejects rather than returning a non-ok response.\n      throw new HttpException({ msg: 'Failed to fetch URL' }, 400);\n    }\n    if (!response.ok) {\n      throw new HttpException({ msg: 'Failed to fetch URL' }, 400);\n    }\n\n    // Guard against OOM: bail out before buffering the whole body into memory.\n    // Content-Length may be absent or wrong, so we re-check the real size after\n    // download too. The type isn't known yet (sniffed below), so the pre-check\n    // uses the largest allowed cap (video).\n    const maxDownloadSize = getMaxSize('video/mp4');\n    const declaredSize = Number(response.headers.get('content-length'));\n    if (declaredSize && declaredSize > maxDownloadSize) {\n      throw new HttpException({ msg: 'File is too large.' }, 400);\n    }\n\n    const buffer = Buffer.from(await response.arrayBuffer());\n    const detected = await fileTypeFromBuffer(buffer);\n    if (!detected || !PUBLIC_API_ALLOWED_MIME.has(detected.mime)) {\n      throw new HttpException({ msg: 'Unsupported file type.' }, 400);\n    }\n\n    if (buffer.length > getMaxSize(detected.mime)) {\n      throw new HttpException({ msg: 'File is too large.' }, 400);\n    }\n\n    const mimetype = detected.mime;\n    const ext = detected.ext;\n\n    const getFile = await this.storage.uploadFile({\n      buffer,\n      mimetype,","sourceCodeStart":115,"sourceCodeEnd":151,"githubUrl":"https://github.com/gitroomhq/postiz-app/blob/0f1647f7491a217d43eb5ae7a480484bdf0aff3e/apps/backend/src/public-api/routes/v1/public.integrations.controller.ts#L115-L151","documentation":"Before buffering the downloaded body, uploadsFromUrl compares the response's Content-Length header against the maximum allowed size for video (the largest cap, since the type isn't sniffed yet). If the declared size exceeds that cap, it throws 400 'File is too large.' to avoid OOM from buffering a huge file.","triggerScenarios":"POST /public/v1/uploads/from-url pointing at a file whose Content-Length header exceeds the video max size (e.g. a 500MB mp4 when the cap is lower), or a server that reports an inflated/incorrect Content-Length.","commonSituations":"Trying to side-load large videos instead of using the direct upload route; CDN misreporting sizes; developers unaware that URL-based upload enforces the same size caps as multipart upload.","solutions":["Check the file's Content-Length (curl -I) and compress/downscale it below the allowed video cap before passing the URL","Use the direct upload endpoint for large files if applicable","If the header is wrong on your server, fix the origin to report accurate Content-Length"],"exampleFix":"// before\n{ \"url\": \"https://example.com/4k-raw-video.mov\" } // 2GB\n\n// after\n{ \"url\": \"https://example.com/compressed-video.mp4\" } // under the size cap","handlingStrategy":"validation","validationCode":"const size = Number((await fetch(url, { method: 'HEAD' })).headers.get('content-length'));\nif (size > MAX_VIDEO_CAP) throw new Error(`File is ${size} bytes — compress below the cap`);","typeGuard":"null","tryCatchPattern":"null","preventionTips":["Check Content-Length via HEAD before submitting","Compress videos below the platform cap","Keep accurate Content-Length headers on your origin"],"tags":["file-size","upload","validation","public-api"],"backgroundTag":"file-size-limit-exceeded","analyzedSha":"0f1647f7491a217d43eb5ae7a480484bdf0aff3e","analyzedAt":"2026-08-27T12:09:55.020Z","schemaVersion":2},"datasetVersion":"2026-08-27T13:17:12.746Z"}