ErrLookup › Background articles › "File too large" / "file size exceeds limit" errors: why libraries cap file sizes and how to fix them
"File too large" / "file size exceeds limit" errors: why libraries cap file sizes and how to fix them
"File too large", "file size exceeds limit", "Image must be less than XMB", and "exceeds the input size limit" are size-cap errors raised before or during a file operation when an input exceeds a library's configured maximum. Developers hit them when uploading media or archives, importing large recordings, passing big payloads to APIs, or processing files whose size a helper refuses to read into memory.
Distilled from 95 documented records across 46 repositories.
Background
This family sits at a deliberate boundary: nearly every implementation checks the file's byte size against a hard cap before committing an expensive or dangerous operation — reading bytes into memory, base64-encoding for an AI provider, uploading to storage, or POSTing to a transcription API. The caps exist for concrete reasons. Meetily's 20 GiB audio cap and GitNexus's 512 KiB index cap exist because files are decoded or read whole into memory (meetily accumulates all samples into a Vec<f32>, multiplying the compressed size several-fold). Zeroclaw's 25 MB audio ceiling and Gumroad's image cap mirror upstream provider limits (Whisper-compatible cloud APIs and Stripe's combined evidence budget, respectively). Others bound artifacts by design: CodeWhale refuses lane exit receipts over 4 KiB so the receipt stays a fixed-size, cheap-to-validate file, and zeroclaw's 50 MB WASM cap rejects modules that are almost certainly the wrong artifact — a debug build with DWARF or a bundle with embedded assets.
From the caller's side, these errors are usually deterministic and cheap: most implementations pre-check metadata rather than reading the payload. Codex's read_bounded_local_media compares file.metadata().len() to the cap before any bytes are read; Remotion's downloadRemoteAsset aborts on an oversized Content-Length header; AFFiNE's CloudBlobStorage.set() fails fast client-side before any network upload starts; Label Studio sums uploaded sizes (or a URL's Content-Length) before downloading. Some libraries check in multiple places: Siyuan enforces its 32 MiB HEIF cap at every entry point (convert, ImageSize, limited reads, and cache), and ECC gates at fstat, again after reading in chunks (catching files that grew mid-read or procfs-style files reporting size 0), and a third time at document-parse level. A subtler variant is Gumroad's dispute-evidence cap, which is not a constant at all — it is the remaining Stripe combined-size budget, so the effective per-file ceiling shrinks as other evidence files are attached.
Because most checks are deterministic, retrying the same input reproduces the error exactly — several records explicitly warn not to retry the same URL or file. The fix pattern is correspondingly uniform: shrink, split, re-encode, or raise the cap (where it is configurable). The knobs vary widely: some limits are hardcoded class constants (Chatbot UI's 2 MB profile image, unopim's 10 MB MAX_FILE_BYTES requiring a subclass), some are environment variables (AFFiNE_BLOB_SIZE_LIMIT, Label Studio's TASKS_MAX_FILE_SIZE, BookStack's APP_UPLOAD_LIMIT), some are php.ini pairs (October's upload_max_filesize/post_max_size), and zeroclaw layers three separate audio caps (a manager-wide global, a per-provider local_whisper cap, and the hardcoded 25 MB cloud cap) whose effective limit is the minimum that applies. Messages often embed the exact cap and actual size, which makes them self-diagnosing — though unopim's blank-size variant means filesize() failed (unreadable file), not an oversized image.
Common causes
- Oversized media uploads. Camera photos, phone videos, and screen recordings routinely exceed per-file caps like Chatbot UI's 2 MB profile limit, AFFiNE's 10 MB blob limit, or meetily's 20 GiB audio cap. iPhone HEIC originals and 4K recordings are frequent offenders, and container size counts — a video-heavy MP4 hits meetily's total-size cap even though its audio track is tiny.
- Long uncompressed audio. Multi-hour WAV recordings grow far past provider caps: zeroclaw rejects audio over the 25 MB Whisper-compatible cloud limit, and a 24-hour 48 kHz stereo WAV is ~15.5 GiB. Compressed containers (Opus, MP3, M4A) fit vastly more duration per byte.
- Server-side limits not matched to the proxy or config. October's PHP cap is the smaller of upload_max_filesize and post_max_size, and a mismatched Nginx client_max_body_size or Apache LimitRequestBody can block uploads before the app sees them. BookStack's APP_UPLOAD_LIMIT and Label Studio's TASKS_MAX_FILE_SIZE must be raised explicitly when legitimate imports grow.
- Unbounded file growth between checks. ECC re-checks size after reading because files can grow between fstat and the read (concurrent appends), and ruflo's 1 MB worker-persistence cap is usually exceeded because state was appended instead of atomically rewritten. Special filesystems reporting size 0 while streaming data trip the same second check.
- Wrong or bloated artifacts. Zeroclaw's 50 MB WASM cap fires on unstripped debug builds or bundles with embedded assets; GitNexus skips minified bundles, lockfiles, and generated data over its index cap; CodeWhale's 1 MiB environment guard catches stale or foreign files in reused directories. The file is often not the artifact you meant to supply.
- Budget that shrinks with each file. Gumroad's dispute-evidence limit is the remaining Stripe combined-size budget, not a fixed constant, so a file that fit yesterday can fail after other large evidence files were attached. Re-read the effective cap before each submission.
- Unreadable files masquerading as oversized. unopim prints an empty size when filesize() returns false due to permissions or open_basedir — 'file too large ( bytes...)' means stat failure, not an oversized image. Fix the path or permissions instead of re-encoding.
What usually fixes it
- [object Object]
- [object Object]
- [object Object]
- [object Object]
- [object Object]
Documented occurrences
- File too large: {:.2}GB. Maximum supported size is {}GB (Zackriya-Solutions/meetily)
- {kind} input exceeds {max_bytes} bytes (openai/codex)
- editor::lang.filesystem.too_large (octobercms/october)
- File size %{size} exceeds limit of %{limit} (gitlabhq/gitlabhq)
- Audio file too large ({} bytes, max {MAX_AUDIO_BYTES}) (zeroclaw-labs/zeroclaw)
- ImageUploadStep: file too large (%s bytes, max %s) — %s (unopim/unopim)
- ErrInputTooLarge: HEIF image exceeds the input size limit (siyuan-note/siyuan)
- Skipped ${skippedLarge} large files (>${maxFileSizeBytes / 1024}KB${suffix}) (abhigyanpatwari/GitNexus)
- Remote asset exceeds the 50MB size limit (remotion-dev/remotion)
- Vagrant is automatically disabling direct upload to backend storage. Uploads directly to backend storage are currently only supported for files 5G in size or smaller. Box file to upload is: %{size} (hashicorp/vagrant)
- One of the uploaded files exceeds the maximum size allowed. (antiwork/gumroad)
- Vagrant is automatically disabling direct upload to backend storage. Uploads directly to backend storage are currently only supported for files 5G in size or smaller. Box file to upload is: %{size} (hashicorp/vagrant)
- Audio file too large ({} bytes, global max {}) (zeroclaw-labs/zeroclaw)
- serialized lane exit receipt exceeds size bound (Hmbown/CodeWhale)
- Memory document ${sourcePath} is too large. (affaan-m/ECC)
- That file is too large. Images can be up to #{MAX_IMAGE_BYTES / 1.megabyte} MB. (antiwork/gumroad)
- File too large: ${stats.size} > ${maxSize} (ruvnet/ruflo)
- ${label} is too large (maximum ${maxBytes} bytes). (affaan-m/ECC)
- ${label} is too large (${opened.size} bytes). (affaan-m/ECC)
- file size (%d bytes) exceeds maximum of %d bytes (wavetermdev/waveterm)
…and 75 more across the corpus — use search.
Honest provenance: generated on 2026-09-04 from AI-assisted analysis of the linked records. See how records are made.