{"record":{"id":"e0cd46a43712d64b","repo":"docling-project/docling","slug":"image-file-image-info-path-exceeds-individual-fi","errorCode":null,"errorMessage":"Image file {image_info.path} exceeds individual file size limit of {self.options.max_file_bytes} bytes","messagePattern":"Image file (.+?) exceeds individual file size limit of (.+?) bytes","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"docling/backend/mets_gbs_backend.py","lineNumber":395,"sourceCode":"        ocr_info = self.page_map[page_no].coordOCR\n        if image_info is None or ocr_info is None:\n            _log.warning(\n                f\"Page {page_no} is missing an 'image' or 'coordOCR' fileGrp entry; \"\n                \"skipping.\"\n            )\n            return None, None\n\n        # Security: limit extraction size to prevent decompression bombs\n        image_file = self._tar.extractfile(image_info.path)\n        if image_file is None:\n            raise RuntimeError(\n                f\"Archive member '{image_info.path}' is not a regular file \"\n                \"(directory or symlink in tar).\"\n            )\n        image_file = cast(tarfile.ExFileObject, image_file)\n        image_data = image_file.read(self.options.max_file_bytes + 1)\n        if len(image_data) > self.options.max_file_bytes:\n            raise ValueError(\n                f\"Image file {image_info.path} exceeds individual file size limit of {self.options.max_file_bytes} bytes\"\n            )\n\n        # Security: Track total bytes extracted\n        self._total_bytes_extracted += len(image_data)\n        if self._total_bytes_extracted > self.options.max_total_bytes:\n            raise ValueError(\n                f\"Total extracted data exceeds maximum limit of {self.options.max_total_bytes} bytes\"\n            )\n\n        buf = BytesIO(image_data)\n        im: PILImage = Image.open(buf)\n\n        ocr_file = self._tar.extractfile(ocr_info.path)\n        if ocr_file is None:\n            raise RuntimeError(\n                f\"Archive member '{ocr_info.path}' is not a regular file \"\n                \"(directory or symlink in tar).\"","sourceCodeStart":377,"sourceCodeEnd":413,"githubUrl":"https://github.com/docling-project/docling/blob/61d76f1ff3f8428065465889f7b4577da7df704c/docling/backend/mets_gbs_backend.py#L377-L413","documentation":"ValueError raised when a page image member inside a METS/GBS archive exceeds options.max_file_bytes after decompression. The image bytes are read with a max_file_bytes+1 cap and rejected if they exceed it — the per-file decompression-bomb guard applied specifically to page images during page conversion.","triggerScenarios":"Converting a METS book whose page scans (PNG/JPEG) are larger than the configured max_file_bytes; trips in _get_page_cells/get_page_image when that page is processed, not at init.","commonSituations":"High-resolution scans (600dpi TIFF-as-PNG pages), archives from labs with huge plates/images, or a lowered max_file_bytes setting. Legitimate large scans are the usual cause rather than an attack.","solutions":["Raise MetsGbsBackendOptions(max_file_bytes=...) above your largest page image size.","Downsample page images before packaging (`mogrify -resize 3000x ...`).","Check which page is oversized via `tar -tvzf book.tar.gz | sort -k3 -n | tail`.","Keep the limit for untrusted archives; only raise it for trusted internal digitization pipelines."],"exampleFix":"# before\nresult = converter.convert(mets_path)  # ValueError: image exceeds size limit\n\n# after\nopts = MetsGbsBackendOptions(max_file_bytes=256 * 1024 * 1024)\n# wire into converter format options, then convert\nresult = converter.convert(mets_path)","handlingStrategy":"validation","validationCode":"import tarfile\n\ndef images_within_cap(tar_path: str, cap: int) -> bool:\n    with tarfile.open(tar_path) as t:\n        return all(m.size <= cap for m in t.getmembers() if m.name.endswith(('.png', '.jpg', '.jpeg')))","typeGuard":null,"tryCatchPattern":"try:\n    result = converter.convert(mets_path)\nexcept ValueError as e:\n    if 'exceeds individual file size limit' in str(e):\n        opts = MetsGbsBackendOptions(max_file_bytes=CAP)\n        result = converter_with(opts).convert(mets_path)\n    else:\n        raise","preventionTips":["Size max_file_bytes above the largest page image, measured from tar metadata.","Downsample scans at packaging time instead of raising limits without bound.","Track which page fails so a retry can skip or replace just that image."],"tags":["mets","archive","security","limits","image"],"backgroundTag":null,"analyzedSha":"61d76f1ff3f8428065465889f7b4577da7df704c","analyzedAt":"2026-08-14T23:53:18.727Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}