{"record":{"id":"e0c74b909845b5bb","repo":"ocrmypdf/OCRmyPDF","slug":"failed-to-load-required-fallback-font-font-file","errorCode":null,"errorMessage":"Failed to load required fallback font {font_file}: {e}","messagePattern":"Failed to load required fallback font (.+?): (.+?)","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"critical","filePath":"src/ocrmypdf/font/font_provider.py","lineNumber":129,"sourceCode":"            font_path = self.font_dir / font_file\n            if not font_path.exists():\n                if font_name == 'Occulta':\n                    raise FileNotFoundError(\n                        f\"Required fallback font not found: {font_path}\"\n                    )\n                log.warning(\n                    \"Font %s not found at %s - OCR output quality for some \"\n                    \"scripts may be affected\",\n                    font_name,\n                    font_path,\n                )\n                continue\n\n            try:\n                self._fonts[font_name] = FontManager(font_path)\n            except Exception as e:\n                if font_name == 'Occulta':\n                    raise ValueError(\n                        f\"Failed to load required fallback font {font_file}: {e}\"\n                    ) from e\n                log.warning(\n                    \"Failed to load font %s: %s - OCR output quality may be affected\",\n                    font_name,\n                    e,\n                )\n\n    def get_font(self, font_name: str) -> FontManager | None:\n        \"\"\"Get a FontManager for the named font.\"\"\"\n        return self._fonts.get(font_name)\n\n    def get_available_fonts(self) -> list[str]:\n        \"\"\"Get list of available font names.\"\"\"\n        return list(self._fonts.keys())\n\n    def get_fallback_font(self) -> FontManager:\n        \"\"\"Get the glyphless fallback font.\"\"\"","sourceCodeStart":111,"sourceCodeEnd":147,"githubUrl":"https://github.com/ocrmypdf/OCRmyPDF/blob/5074a0b0e109362422b768fd271ed84bf717c4ec/src/ocrmypdf/font/font_provider.py#L111-L147","documentation":"Even when the Occulta font file exists, wrapping it in a FontManager can fail (corrupt ttf, unreadable bytes, incompatible font library). Because Occulta is required for sandwich PDFs, any load failure is escalated to ValueError from FontProvider.__init__.","triggerScenarios":"FontProvider init where font_dir/Occulta*.ttf exists but is corrupted, zero bytes, truncated by a partial download, or unreadable due to permissions.","commonSituations":"Tampered or truncated data files, odd filesystems returning short reads, font library version incompatibilities.","solutions":["Reinstall the package to replace the font file.","Verify the file: nonzero size, valid TTF magic (00 01 00 00), readable permissions; restore from a good copy if broken.","Check the chained cause for the underlying font-parsing error."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"from pathlib import Path\np = Path(font_dir) / 'Occulta.ttf'\nassert p.exists() and p.stat().st_size > 1000 and p.read_bytes()[:4] == b'\\x00\\x01\\x00\\x00'","typeGuard":null,"tryCatchPattern":"try:\n    provider = FontProvider(...)\nexcept ValueError as e:\n    if 'Failed to load required fallback font' in str(e):\n        restore_font_from_package(); provider = FontProvider(...)","preventionTips":["Verify TTF files are intact after any file-copy/deploy step.","Reinstall the wheel if font parsing fails; inspect e.__cause__ for details."],"tags":["ocrmypdf","fonts","corrupt-file","font-loading"],"backgroundTag":"corrupt-packaged-resource","analyzedSha":"5074a0b0e109362422b768fd271ed84bf717c4ec","analyzedAt":"2026-08-27T11:57:38.523Z","schemaVersion":2},"datasetVersion":"2026-08-27T13:17:12.746Z"}