MinerU Configuration and Provider Resolution#
Overview#
MinerU is registered in RAGFlow as an OCR-type model provider, not a vision model. This distinction is the root of several bugs and misconfigurations: any code path or UI element that treats the layout_recognize value as a vision model reference will fail when MinerU is selected. The core entry point is by_mineru() in rag/app/naive.py, which resolves the MinerU provider, configures the parser, and dispatches to MinerUParser.parse_pdf().
Configuration Sources#
MinerU's runtime configuration is assembled from three sources in priority order (highest first):
- UI-provisioned config — stored as JSON in the tenant model instance's
api_keyfield with lowercase keys (e.g.,"mineru_apiserver"). Comes in either nested ({"api_key": {...}}) or flat form. - Env-auto-provisioned config — uppercase
MINERU_*keys written whenensure_mineru_from_env()is called; stored in the sameapi_keyfield. - Direct environment variables — read at model instantiation time as a final fallback.
The resolution logic lives in MinerUOcrModel.__init__():
| Field | UI key | Env var | Default |
|---|---|---|---|
| API server URL | mineru_apiserver | MINERU_APISERVER | "" |
| Output directory | mineru_output_dir | MINERU_OUTPUT_DIR | "" |
| Backend | mineru_backend | MINERU_BACKEND | "pipeline" |
| VLM server URL | mineru_server_url | MINERU_SERVER_URL | "" |
| Delete output | mineru_delete_output | MINERU_DELETE_OUTPUT | 1 (True) |
The full list of recognized env keys is MINERU_ENV_KEYS in common/constants.py.
parser_config Fields Consumed by MinerU#
The knowledge base / document parser_config dict carries these MinerU-specific fields, read in parse_pdf():
| Field | Key in parser_config | Default |
|---|---|---|
| OCR language | mineru_lang | falls back to lang kwarg |
| Parse method | mineru_parse_method | "auto" |
| Formula detection | mineru_formula_enable | True |
| Table detection | mineru_table_enable | True |
The mineru_lang value is mapped to MinerU's internal language codes via LANGUAGE_TO_MINERU_MAP — for example, "English" → "en", "Chinese" → "ch". An unrecognized language silently falls back to "ch".
OCR Provider Resolution in by_mineru()#
by_mineru() uses a two-stage fallback to find the MinerU model:
- Tenant model lookup:
get_first_provider_model_name(tenant_id, "MinerU", LLMType.OCR)— finds the first active OCR model registered under the"MinerU"provider for this tenant . - Env fallback:
ensure_mineru_from_env(tenant_id)— readsMINERU_*env vars, auto-provisions a synthetic tenant model row if needed, and returns a composite model name"mineru-from-env@<instance>@MinerU".
Once a model name is resolved, it calls resolve_model_config(tenant_id, LLMType.OCR, mineru_llm_name) to fetch the full config dict, then instantiates an LLMBundle whose .mdl is a MinerUOcrModel instance.
MinerU is an OCR provider. Any lookup that requests LLMType.VISION against a MinerU model ID will fail — see the Known Bug section below.
layout_recognize and normalize_layout_recognizer()#
The layout_recognize field in parser_config controls which OCR/layout backend handles documents. normalize_layout_recognizer() in common/parser_config_utils.py normalizes this value:
- Strings ending with
@mineru→layout_recognizer = "MinerU",parser_model_name= full composite name - Strings ending with
@paddleocr→"PaddleOCR" - Strings ending with
@opendataloader→"OpenDataLoader" - Strings ending with
@somark→"SoMark" "MinerU"(plain string) → passes through unchanged;parser_model_name = None
When layout_recognize = "MinerU" and parser_model_name is None, by_mineru() auto-discovers the provider via get_first_provider_model_name() or the env fallback.
When layout_recognize = "my-model@instance@MinerU", the composite name is passed as mineru_llm_name directly, pinning the specific model instance.
Known Bug: UUID in layout_recognize (v0.26.4)#
Symptom: Provider not found for model <uuid> / TenantModel id=<uuid> cannot be used as vision model during chunking.
Root cause (confirmed in Issue #17114): The frontend in v0.26.4 stored the MinerU model's database UUID directly into layout_recognize instead of the canonical string "MinerU". The backend then routes through by_plaintext(), which calls resolve_model_config(tenant_id, LLMType.VISION, layout_recognizer). This fails in two cascading steps :
get_model_config_by_id()finds the model row but rejects it:TenantModel id=<uuid> cannot be used as vision model(it is registered as OCR, not VISION).- The fallback
get_model_config_from_provider_instance()tries to parse the UUID asmodel@instance@providerviasplit_model_name(), gets an empty provider string, and raisesProvider not found for model <uuid>.
Additional wrinkle: Updating kb_parser_config.layout_recognize at the dataset level does not retroactively fix documents already uploaded — each document retains its own stale parser_config copy . Both the dataset and each affected document must be patched individually.
Fixes: PRs #16782 and #15858 addressed the frontend bug.
Workaround for affected installations: Use the REST API to set layout_recognize to "MinerU" on both the dataset and each affected document, then re-parse.
Remote / Online MinerU API#
RAGFlow has no hardcoded localhost restriction. MINERU_APISERVER can point to any remote URL; RAGFlow will POST to {MINERU_APISERVER}/file_parse and expect a ZIP response . The remote server must implement the open-source MinerU API contract — specifically POST /file_parse returning a ZIP with content_list.json, middle.json, and page images . The vlm-http-client backend additionally requires MINERU_SERVER_URL pointing to a remote VLM server .
Key Files#
| File | Purpose |
|---|---|
deepdoc/parser/mineru_parser.py | MinerUParser — HTTP client, parse_pdf(), MinerUParseOptions, backend/language enums |
rag/llm/ocr_model.py | MinerUOcrModel — config resolution, check_available(), delegates to MinerUParser |
rag/app/naive.py | by_mineru() — provider lookup, vision model injection, parse_pdf() call |
common/parser_config_utils.py | normalize_layout_recognizer() — normalizes layout_recognize values |
api/db/joint_services/tenant_model_service.py | get_first_provider_model_name(), ensure_mineru_from_env(), resolve_model_config() |
common/constants.py | MINERU_ENV_KEYS, MINERU_DEFAULT_CONFIG |