mirror of
https://github.com/open-webui/open-webui.git
synced 2026-11-09 10:50:35 -06:00
[GH-ISSUE #17025] issue: Docling integration: Auto-fallback to OCR + use /v1 route to avoid empty content on text-PDFs #33671
Reference in New Issue
Block a user
Originally created by @Soliver84 on GitHub (Aug 29, 2025).
Original GitHub issue: https://github.com/open-webui/open-webui/issues/17025
Check Existing Issues
Installation Method
Pip Install
Open WebUI Version
v0.6.26
Ollama Version (if applicable)
Nix OPENAI
Operating System
Windows Server 2022
Browser (if applicable)
Edge
Confirmation
README.md.Expected Behavior
Expected behavior
Text-PDFs: Extract plain text (no OCR), stable even for large files.
Image/scan PDFs: If the first attempt yields no text, automatically retry with OCR (e.g., Tesseract eng,deu).
API path: Use the stable /v1/convert/file; for older Docling-Serve builds optionally fall back to /v1alpha/….
Actual Behavior
Actual behavior
With enforced OCR: Tesseract fails on low render DPI → md_content == "" → EMPTY_CONTENT.
Without OCR & without fallback: scan-only PDFs remain empty.
Docling-Serve is currently called via /v1alpha/convert/file; newer builds expect /v1/convert/file.
Steps to Reproduce
Steps to reproduce
Start OpenWebUI and Docling-Serve v0.16.1 or Docling Serve v1.3.1 (port 5001).
In OpenWebUI set ocr_engine=tesseract + ocr_lang=eng,deu.
Import a larger text-PDF (> 2 MB).
Observe EMPTY_CONTENT; Docling/Tesseract logs “0 dpi / Too few characters”.
(Optional: Disable OCR and import a scan-PDF → no automatic OCR fallback is attempted.)
Logs & Screenshots
Hier sind die relevanten Log-Auszüge, kompakt und bereit zum Einfügen ins Ticket:
OpenWebUI
Docling-Serve (v0.16.1)
Kurzkontext für Reviewer: Docling wird via
/v1alpha/convert/fileerfolgreich (200) aufgerufen, aber Tesseract-OSD scheitert aufgrund sehr niedriger effektiver DPI („0→70/206“), meldet „Too few characters. Skipping this page“. Dadurch kommtmd_content=""zurück und OpenWebUI bricht mitEMPTY_CONTENT/HTTP 400 ab.Additional Information
Title: Docling integration: Auto-fallback to OCR + use /v1 route to avoid empty content on text-PDFs
Components: OpenWebUI → Retrieval → DoclingLoader (open_webui/retrieval/loaders/main.py)
Versions/Setup:
OpenWebUI (local, Windows, venv)
Docling-Serve v0.16.1 (CPU Docker, port 5001)
OpenWebUI talks to Docling over HTTP (Nginx proxy present but not required to reproduce)
Sometimes ocr_engine=tesseract + ocr_lang=eng,deu set in OpenWebUI
Embedding model: text-embedding-3-large (not relevant for extraction)
Problem description
Importing larger text-based PDFs (e.g., “Effective C++.pdf”, > 2 MB) results in empty content in OpenWebUI. UI shows:
ValueError: The content provided is empty. Please ensure that there is text or data present before proceeding.
Docling/Tesseract logs at the same time:
Warning: Invalid resolution 0 dpi. Using 70 instead.
Too few characters. Skipping this page.
Key point: If OpenWebUI has an OCR engine configured (Tesseract), OCR is always enforced — even for text-PDFs. Docling renders pages at a very low default (~72 DPI). Tesseract receives tiny/blurred pages; OSD detects “too few characters” and skips pages → empty md_content → OpenWebUI raises EMPTY_CONTENT.
If no OCR parameters are sent, Docling will read the text layer, but there is no automatic OCR fallback if a PDF actually has no text (scan).
In short:
Enforced OCR: breaks on text-PDFs due to DPI/OSD heuristics → empty results.
No OCR & no fallback: scans remain empty.
Expected behavior
Text-PDFs: Extract plain text (no OCR), stable even for large files.
Image/scan PDFs: If the first attempt yields no text, automatically retry with OCR (e.g., Tesseract eng,deu).
API path: Use the stable /v1/convert/file; for older Docling-Serve builds optionally fall back to /v1alpha/….
Actual behavior
With enforced OCR: Tesseract fails on low render DPI → md_content == "" → EMPTY_CONTENT.
Without OCR & without fallback: scan-only PDFs remain empty.
Docling-Serve is currently called via /v1alpha/convert/file; newer builds expect /v1/convert/file.
Steps to reproduce
Start OpenWebUI and Docling-Serve v0.16.1 (port 5001).
In OpenWebUI set ocr_engine=tesseract + ocr_lang=eng,deu.
Import a larger text-PDF (> 2 MB).
Observe EMPTY_CONTENT; Docling/Tesseract logs “0 dpi / Too few characters”.
(Optional: Disable OCR and import a scan-PDF → no automatic OCR fallback is attempted.)
Root cause
Forcing OCR on text-PDFs is unnecessary and fragile (DPI/OSD heuristics in Tesseract).
Docling’s default PDF render DPI (~72) is too low for reliable OCR; OSD skips pages.
OpenWebUI has no auto-fallback (first try text, then OCR), thus either OCR is enforced (and may fail) or never attempted.
Proposed fix (code changes)
A) Auto-fallback inside DoclingLoader (no infinite loop)
First call: send to Docling without OCR parameters.
If md_content is empty and the user did not explicitly force OCR →
Second call (fallback): retry with ocr_engine="tesseract", ocr_lang=["eng","deu"].
Clean logging; if the user forces OCR, we keep the current behavior (no fallback).
B) Modernize API route
In _post(), hit /v1/convert/file first. If 404/405/501, fallback to /v1alpha/convert/file for older Docling-Serve tags.
Patch (diff)
File: open_webui/retrieval/loaders/main.py – class DoclingLoader
@@
class DoclingLoader:
def init(self, url, file_path=None, mime_type=None, params=None):
self.url = url.rstrip("/")
self.file_path = file_path
self.mime_type = mime_type
self.params = params or {}
Why this makes sense (OCR background)
Avoid unnecessary OCR: Text-PDFs should never be degraded by OCR. Auto-fallback guarantees: try text layer first, OCR only if needed.
Resilient to Tesseract heuristics: Low default DPI (~72) and OSD thresholds often cause “Too few characters → skip.” By minimizing OCR use and only retrying when necessary, we avoid fragile paths.
Better UX: No more “empty” imports. Scans work without toggling settings; text-PDFs remain fast.
Backward-compat: Prefer /v1; older Docling-Serve builds still work via automatic /v1alpha fallback.
Performance impact: Only an extra HTTP call in rare fallback cases; success path stays single-shot.
Follow-ups (optional)
In UI, do not prefill ocr_engine by default.
(Later) Expose OCR knobs (psm, min_characters_to_try) and Docling render images_scale in advanced settings.
Tests:
Large text-PDF → no OCR, success.
Scan-PDF → first attempt empty, OCR fallback yields text.
User forces OCR → no fallback; keep current single-path behavior.
@BakirBukvic commented on GitHub (Aug 29, 2025):
I had a similar issue. A workaround is to setup your own docling server, without using the docker image. Then connect it through custom document engine.
And then handle the logic there. If text page, then don't use OCR. If image, then use OCR.
It's not a fix, just a workaround.
@Soliver84 commented on GitHub (Aug 29, 2025):
@BakirBukvic
I also have Docling an openwebu running locally.
Can you give me your configuration, how it works for you with all PDFs, even larger ones up to 80MB?
And also what exactly you've configured in openwebui. I've disabled Tesseract OCR.
@tjbck commented on GitHub (Aug 31, 2025):
PR welcome.