paperclipai/paperclip · error
Invalid HEIF box structure
Error message
Invalid HEIF box structure
What it means
The same bounded ISO-BMFF walker throws "Invalid HEIF box structure" when the per-container box count exceeds 4096 or fewer than 8 bytes remain where a box header is required. It is a structural sanity check ensuring the buffer parses as well-formed ISO-BMFF boxes before native decoding.
Solutions
- Re-download/re-export the image — the file is corrupt or truncated; verify with `heif-info` or `ffprobe`.
- Confirm the declared content type matches the actual bytes (magic bytes should be ftyp).
- Re-encode the source image to HEIC with standard tooling before uploading.
- If malicious input is suspected, keep it blocked; this guard is intentional.
Example fix
// verify before upload // before: truncated file.heic (cut off mid-transfer) // after: ffprobe file.heic && re-export, or compare byte size against source
Defensive patterns
Strategy: validation
Validate before calling
function heifStructureLooksSane(buf: Buffer): boolean {
if (buf.length < 12 || buf.toString("ascii", 4, 8) !== "ftyp") return false;
let at = 0, boxes = 0;
while (at + 8 <= buf.length && boxes++ < 4096) {
const size = buf.readUInt32BE(at);
if (size < 8 && size !== 0) return false;
at += size === 0 ? buf.length - at : size;
}
return at <= buf.length;
} Type guard
function hasFtypHeader(b: Buffer): b is Buffer {
return b.length >= 12 && b.toString("ascii", 4, 8) === "ftyp";
} Try / catch
try {
validateHeifDimensions(body);
} catch (e) {
if (e instanceof Error && e.message === "Invalid HEIF box structure") {
return rejectUpload("File is truncated or not valid HEIF; please re-export it");
}
throw e;
} Prevention
- Verify uploads complete (checksum/byte count) before validation.
- Run a local ffprobe/heif-info sanity check in tooling before submitting files.
- Reject content types that don't match magic bytes early in the upload path.
- Treat thousands of tiny boxes as malicious; never relax the 4096 cap for untrusted input.
When it happens
Trigger: A HEIF buffer containing more than 4096 sibling boxes in one container, or a truncated buffer where the remaining range (end - at) is < 8 bytes mid-iteration (media.ts:24-25).
Common situations: Corrupted or truncated HEIC upload (incomplete download/transfer); fuzzed or malicious file with thousands of tiny boxes; non-HEIF bytes declared with an image/heic content type.
Understand the failure class
Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.
Related errors
- Invalid HEIF box length
- HEIF file type is missing
- HEIF metadata nesting is too deep
- Invalid HEIF image dimensions
- HEIF box exceeds file bounds
AI-assisted analysis of paperclipai/paperclip@3f1d897a7c (2026-09-18).
Data as JSON: /api/errors/f4dee4cbd2d5305f.
Report an issue: GitHub.
Appendix: source
Thrown at server/src/services/photon/media.ts:25
const MAX_PIXELS = 50_000_000;
export const HEIF_CONTENT_TYPES = new Set([
"image/heic",
"image/heif",
"image/heic-sequence",
"image/heif-sequence",
]);
/** Validate bounded ISO-BMFF structure before invoking any native decoder. */
export function validateHeifDimensions(body: Buffer): void {
let boxes = 0;
let dimensions = 0;
let totalPixels = 0;
let branded = false;
const visit = (start: number, end: number, depth: number) => {
if (depth > 8) throw new Error("HEIF metadata nesting is too deep");
for (let at = start; at < end; ) {
if (++boxes > 4096 || end - at < 8)
throw new Error("Invalid HEIF box structure");
let size = body.readUInt32BE(at);
const type = body.toString("ascii", at + 4, at + 8);
let header = 8;
if (size === 1) {
if (end - at < 16) throw new Error("Invalid HEIF box length");
const extended = body.readBigUInt64BE(at + 8);
if (extended > BigInt(body.length))
throw new Error("HEIF box exceeds file bounds");
size = Number(extended);
header = 16;
} else if (size === 0) size = end - at;
if (size < header || at + size > end)
throw new Error("HEIF box exceeds file bounds");
const content = at + header;
if (type === "ftyp") {
if (size < header + 8) throw new Error("HEIF file type is missing");
const brands = body.toString("ascii", content, at + size);
branded = /heic|heix|hevc|hevx|mif1|msf1/.test(brands);View on GitHub (pinned to 3f1d897a7c)