HKUDS/DeepTutor · error · MinerUError

MinerU parsing timed out after {int(timeout)}s (last state:

Error message

MinerU parsing timed out after {int(timeout)}s (last state: {last_state or 'unknown'}).

What it means

The cloud job did not reach a terminal state before the monotonic deadline (timeout seconds). The last observed state is included for diagnosis.

Source

Thrown at deeptutor/services/parsing/engines/mineru/cloud.py:201

                report = f"MinerU cloud: {state or 'queued'}"
                if total_pages:
                    report += f" ({progress.get('extracted_pages') or 0}/{total_pages} pages)"
                if report != last_report:
                    last_report = report
                    try:
                        on_progress(report)
                    except Exception:
                        on_progress = None
            if state == _TERMINAL_OK:
                zip_url = str(entry.get("full_zip_url") or "").strip()
                if not zip_url:
                    raise MinerUError("MinerU reported done but returned no full_zip_url.")
                return zip_url
            if state == _TERMINAL_FAIL:
                err = str(entry.get("err_msg") or "unknown error")
                raise MinerUError(f"MinerU failed to parse the document: {err}")
        if time.monotonic() >= deadline:
            raise MinerUError(
                f"MinerU parsing timed out after {int(timeout)}s "
                f"(last state: {last_state or 'unknown'})."
            )
        time.sleep(poll_interval)


def verify_credentials(config: MinerUConfig) -> None:
    """Best-effort connectivity / token check for the Settings → MinerU "Test"
    button. Requests an upload slot (which does not consume parsing quota and
    is never followed by an upload, so it simply expires) and validates the
    business code. Raises :class:`MinerUError` with a user-facing message on
    any failure."""
    if not config.api_keys:
        raise MinerUError("No API token configured.")
    base_url = config.api_base_url.rstrip("/")
    key_pool = KeyPool(config.api_keys)
    body: dict[str, object] = {
        "files": [{"name": "connectivity-check.pdf", "is_ocr": False}],

View on GitHub (pinned to 3e82f13042)

Solutions

  1. Increase the timeout passed to parse_cloud for large documents.
  2. Retry — jobs often finish on a second submission.
  3. Reduce PDF size (split pages) if consistently timing out.
  4. Check the last_state value: 'waiting/running' means slow; unknown means polling itself may be failing.

Example fix

# before
parse_cloud(pdf, wd, cfg, timeout=300)

# after
parse_cloud(pdf, wd, cfg, timeout=1800)  # large PDFs
Defensive patterns

Strategy: retry

Validate before calling

timeout = max(600, pages * 8)  # scale with document size

Try / catch

try:
    parse_cloud(pdf, wd, cfg, timeout=1800)
except MinerUError as e:
    if "timed out" in str(e):
        queue_retry(pdf)  # job may still complete server-side

Prevention

When it happens

Trigger: Polling until time.monotonic() >= deadline — slow MinerU queue, very large PDFs, or a low configured timeout.

Common situations: Batch-hour congestion, 500+ page documents, aggressive timeout values, or a stuck 'running' state server-side.

Understand the failure class

Related errors


AI-assisted analysis of HKUDS/DeepTutor@3e82f13042 (2026-08-27). Data as JSON: /api/errors/2157db3a3380a7a6. Report an issue: GitHub.