HKUDS/DeepTutor · error · MinerUError
Failed to upload PDF to MinerU: {exc}
Error message
Failed to upload PDF to MinerU: {exc} What it means
The signed upload URL was obtained, but the HTTP PUT of the PDF bytes failed (network error, DNS, TLS, timeout, or non-2xx status via raise_for_status).
Source
Thrown at deeptutor/services/parsing/engines/mineru/cloud.py:156
file_urls = data.get("file_urls") or []
if not batch_id or not isinstance(file_urls, list) or not file_urls:
raise MinerUError("MinerU API did not return an upload URL (missing batch_id/file_urls).")
return batch_id, str(file_urls[0])
def _upload_file(pdf_path: Path, upload_url: str) -> None:
"""PUT the PDF bytes to the signed URL.
The signed URL carries its own auth; per MinerU's docs we must NOT send an
``Authorization`` or ``Content-Type`` header (a stray Content-Type breaks
the OSS signature).
"""
data = pdf_path.read_bytes()
try:
response = httpx.put(upload_url, content=data, timeout=_UPLOAD_TIMEOUT_SECONDS)
response.raise_for_status()
except httpx.HTTPError as exc:
raise MinerUError(f"Failed to upload PDF to MinerU: {exc}") from exc
def _poll_for_zip(
client: httpx.Client,
batch_id: str,
file_name: str,
*,
key_pool: KeyPool,
poll_interval: float,
timeout: float,
on_progress: Callable[[str], None] | None = None,
) -> str:
"""Poll the batch results until our file is ``done``; return full_zip_url."""
deadline = time.monotonic() + timeout
last_state = ""
last_report = ""
while True:
payload = _get_json(client, f"/api/v4/extract-results/batch/{batch_id}", key_pool)View on GitHub (pinned to 3e82f13042)
Solutions
- Retry the whole parse (a fresh signed URL is requested each attempt).
- Check network/proxy access to the storage host in the upload URL.
- Reduce PDF size or check the timeout budget for large files.
- Verify system clock — signed URLs are time-sensitive.
Example fix
# before
res = parse_pdf_to_workdir(pdf, wd, cfg)
# after
for attempt in range(3):
try:
res = parse_pdf_to_workdir(pdf, wd, cfg); break
except MinerUError as e:
if "upload" not in str(e).lower() or attempt == 2: raise
time.sleep(2 ** attempt) Defensive patterns
Strategy: retry
Validate before calling
def uploadable(pdf: Path) -> bool:
return pdf.is_file() and pdf.stat().st_size < 200 * 1024 * 1024 Try / catch
for i in range(3):
try:
parse_pdf_to_workdir(pdf, wd, cfg); break
except MinerUError as e:
if "upload PDF" not in str(e) or i == 2: raise
time.sleep(2 ** i) Prevention
- Upload promptly after the batch is created (signed URLs expire).
- Compress/split very large PDFs.
- Ensure egress to the object-storage host.
When it happens
Trigger: httpx.put(upload_url, ...) raising httpx.HTTPError — expired signed URL, network drop, proxy blocking the object-store host, or 4xx/5xx from storage.
Common situations: Long delay between requesting the batch and uploading (URL expiry), corporate proxies/firewalls, large PDFs exceeding an upload limit or timing out (_UPLOAD_TIMEOUT_SECONDS).
Related errors
- Failed to download MinerU result archive: {exc}
- MinerU API request failed: {exc}
- MinerU cloud mode is selected but no API token is configured
- PDF file not found: {pdf_path}
- MinerU API did not return an upload URL (missing batch_id/fi
AI-assisted analysis of HKUDS/DeepTutor@3e82f13042 (2026-08-27).
Data as JSON: /api/errors/4890ab4849571bf9.
Report an issue: GitHub.