docling-project / docling-project/docling

Document conversion fails systematically with invalid glyphs encountered when custom fonts present in pdf

Open
#3,965 8 comments 0 reactions 0 assignees View on GitHub
bug
Dominant language
Python
Stars
66.4k
Forks
4.8k
Avg merge
2d 21h
Merged PRs (30d)
84

Description

Bug
On some PDFs (Franchise Disclosure Documents with embedded/custom font encodings), Docling extracts text as a systematic character shift rather than readable Unicode. The garbled text is recoverable by adding 0x1D (29) to most byte values (e.g. %ODFN ? Black, ,WHP ? Item, )5$1&+,6( ? FRANCHISE).

Corruption starts on page 1 and affects nearly the entire document (not a single-page cliff). Layout/structure nodes are produced, but downstream labelers that match Item N / English headings fail because titles never appear as plaintext.

Reproduced with:

default PdfFormatOption backend (DoclingParseV4DocumentBackend)
explicit PyPdfiumDocumentBackend
So this does not appear to be fixed by switching PDF backends alone.

Example (page 1 header text as extracted vs decoded):

Extracted After ord(c)+0x1D
)5$1&+,6(…
FRANCHISE DISCLOSURE DOCUMENT
%ODFN…
Black Rifle Coffee Company LLC
,WHP… (later “Item” headers)
Item 1 …
OCR was off (do_ocr=False).

Steps to reproduce
Install Docling (see versions below).
Convert an affected PDF with OCR disabled, using either default backend or pypdfium2:
from docling.datamodel.base_models import InputFormat
from docling.datamodel.pipeline_options import PdfPipelineOptions
from docling.document_converter import DocumentConverter, PdfFormatOption
from docling.backend.pypdfium2_backend import PyPdfiumDocumentBackend
options = PdfPipelineOptions()
options.do_ocr = False
options.do_table_structure = True
converter = DocumentConverter(
allowed_formats=[InputFormat.PDF],
format_options={
InputFormat.PDF: PdfFormatOption(
pipeline_options=options,
backend=PyPdfiumDocumentBackend, # also fails with default DoclingParseV4
)
},
)
result = converter.convert("affected.pdf")
print(result.document.texts[0].text) # expect shifted garbage, not "FRANCHISE…"
Observe cover/heading text is not readable ASCII/Unicode; applying +0x1D per character recovers English.
Confirm the same pattern with the default backend (omit backend=…).
If useful for triage: failure is document-wide from page 1; “Item N” headings are present in the PDF and decode cleanly after the shift (e.g. first Item 1 around page 6 on one sample). I can attach a minimal redacted page sample if needed (avoid posting full commercial FDDs in public).

Docling version
CE worker / production path where we hit this:

docling==2.66.0
docling-core==2.57.0
docling-parse==4.7.2
Local env (also has Docling installed; CLI noisy with pydantic warnings):

docling 2.73.0
docling-core 2.64.0
docling-parse 4.7.2
pypdfium2 4.30.0
(docling --version / python -m docling --version does not print a clean one-liner in this env; versions above from importlib.metadata.)

Python version
Python 3.12.10
(CE image: python:3.11-slim)

Contributor guide

Open the contributing guide

Research direction

Start with the DocumentConverter setup using the default PdfFormatOption backend and PyPdfiumDocumentBackend, then reproduce the issue with the affected PDF and OCR disabled. Compare extracted text against the expected readable Unicode and verify that headings such as “Item 1” are recovered without applying an external character shift.

Written by the indexing model from the issue text.

Assessment

Tech stack
python
Domain
backend
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
48/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.