{"record":{"id":"9df6a45066225501","repo":"opendatalab/MinerU","slug":"no-healthy-upstream-mineru-api-servers-are-availab","errorCode":null,"errorMessage":"No healthy upstream MinerU API servers are available","messagePattern":"No healthy upstream MinerU API servers are available","errorType":"exception","errorClass":"RuntimeError","httpStatus":null,"severity":"critical","filePath":"mineru/cli/router.py","lineNumber":999,"sourceCode":"\n\nasync def startup_router_state(app: FastAPI, settings: RouterSettings) -> None:\n    http_client = httpx.AsyncClient(\n        timeout=build_http_timeout(),\n        follow_redirects=True,\n    )\n    worker_pool = WorkerPool(settings, http_client)\n    registry = RouterTaskRegistry(\n        task_retention_seconds=settings.task_retention_seconds,\n        cleanup_interval_seconds=settings.task_cleanup_interval_seconds,\n    )\n\n    try:\n        await registry.start()\n        await worker_pool.start()\n        healthy, payload = worker_pool.health_payload()\n        if not healthy:\n            raise RuntimeError(\n                payload.get(\n                    \"error\",\n                    \"No healthy upstream MinerU API servers are available\",\n                )\n            )\n    except Exception:\n        await registry.shutdown()\n        await worker_pool.shutdown()\n        await http_client.aclose()\n        raise\n\n    app.state.http_client = http_client\n    app.state.worker_pool = worker_pool\n    app.state.router_task_registry = registry\n\n\nasync def shutdown_router_state(app: FastAPI) -> None:\n    registry = getattr(app.state, \"router_task_registry\", None)","sourceCodeStart":981,"sourceCodeEnd":1017,"githubUrl":"https://github.com/opendatalab/MinerU/blob/4fe4bde114a23ee5dd637eae99b767f4669bf58c/mineru/cli/router.py#L981-L1017","documentation":"Raised at router startup when the WorkerPool health check reports no healthy upstream MinerU API servers. The router refuses to start (and shuts down the registry, worker pool, and http client) because every configured upstream failed its health probe. The message may come from the health payload's 'error' key, defaulting to this string.","triggerScenarios":"Calling create_app/router startup with MINERU_SERVER_URLS (or equivalent settings) pointing at servers that are down, unreachable, or return non-healthy /health responses; worker_pool.health_payload() returns healthy=False during lifespan startup.","commonSituations":"Upstream MinerU API processes not started yet; wrong host/port in server list; firewall or DNS blocking the health endpoint; upstream containers still booting when the router starts; all servers previously marked unhealthy.","solutions":["Start or fix the upstream MinerU API servers and verify each /health endpoint returns healthy with curl before starting the router","Correct the server URL list in the router configuration (scheme, host, port)","If servers are slow to boot, start them first or add readiness checks so the router starts after upstreams are healthy","Check network/DNS/firewall between the router host and each upstream server"],"exampleFix":"# before\nMINERU_SERVER_URLS=http://localhost:8000  # server not running\n\n# after\n# start upstream first, verify, then run router\ncurl -fsS http://localhost:8000/health\nMINERU_SERVER_URLS=http://localhost:8000 mineru-api-router","handlingStrategy":"validation","validationCode":"import httpx\n\ndef upstreams_healthy(server_urls: list[str], timeout: float = 5.0) -> bool:\n    with httpx.Client(timeout=timeout) as c:\n        return all(\n            c.get(f\"{u.rstrip('/')}/health\").status_code == 200\n            for u in server_urls\n        )","typeGuard":null,"tryCatchPattern":"try:\n    app = create_router_app(settings)\nexcept RuntimeError as exc:\n    if \"No healthy upstream\" in str(exc):\n        log.error(\"upstreams down; not starting router\")\n    raise","preventionTips":["Run health checks (curl /health) on every upstream before starting the router","Keep upstream servers under a supervisor (systemd/docker restart policy) so they recover automatically","Point MINERU_SERVER_URLS at a load balancer with its own health checks","Alert on upstream health so the router never starts into a dead pool"],"tags":["mineru","router","startup","health-check","upstream"],"backgroundTag":null,"analyzedSha":"4fe4bde114a23ee5dd637eae99b767f4669bf58c","analyzedAt":"2026-08-14T21:29:18.456Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}