PaddlePaddle/PaddleOCR · warning · ServiceUnavailableError
Service unavailable: {msg}
Error message
Service unavailable: {msg} What it means
Raised as ServiceUnavailableError by raise_for_status() when the HTTP response status is 503 or 504. The exception carries the status code plus the message. It indicates a server-side or gateway problem (overload, maintenance, upstream timeout), typically transient and worth retrying with backoff.
Source
Thrown at paddleocr/_api_client/_core.py:158
job_id=job_id,
state=state,
progress=progress,
result=data.get("resultUrl"),
error_msg=data.get("errorMsg"),
)
def raise_for_status(status_code: int, msg: str) -> None:
if 200 <= status_code < 300:
return
if status_code in (401, 403):
raise AuthError(f"Authentication failed: {msg}")
if status_code == 400:
raise InvalidRequestError(f"Bad request: {msg}")
if status_code == 429:
raise RateLimitError(f"Rate limit exceeded: {msg}")
if status_code in (503, 504):
raise ServiceUnavailableError(status_code, f"Service unavailable: {msg}")
raise APIError(status_code, msg)
def unwrap_api_response(payload: dict, status_code: int) -> dict:
if not isinstance(payload, dict):
raise ResponseFormatError("Response body must be a JSON object.")
code = payload.get("code", 0)
if code not in (0, None):
raise APIError(status_code, extract_api_message_from_payload(payload) or "")
data = payload.get("data")
if not isinstance(data, dict):
raise ResponseFormatError("Response JSON must contain object field 'data'.")
return data
def extract_job_id(data: dict) -> str:
job_id = data.get("jobId")
if not isinstance(job_id, str) or not job_id:View on GitHub (pinned to 2661c7c0ef)
Solutions
- Retry the same request after a short backoff (seconds, then exponential), ideally 3-5 attempts.
- Check the service status page for ongoing incidents.
- Reduce request size (smaller files) if 504s correlate with large uploads.
- If persistent, report with timestamps to the service operator.
Example fix
# before
result = await client.ocr(file_path="big.pdf")
# after
import asyncio
for attempt in range(5):
try:
result = await client.ocr(file_path="big.pdf")
break
except ServiceUnavailableError:
await asyncio.sleep(2 ** attempt) Defensive patterns
Strategy: retry
Try / catch
from paddleocr._api_client.errors import ServiceUnavailableError
import asyncio
async def with_backoff(fn, *a, attempts=5, **kw):
for i in range(attempts):
try:
return await fn(*a, **kw)
except ServiceUnavailableError:
if i == attempts - 1:
raise
await asyncio.sleep(2 ** i) Prevention
- Retry 503/504 with exponential backoff; they are transient by nature.
- Check the service status page before debugging your own code.
- Alert only after several consecutive failures.
When it happens
Trigger: Any API call during service maintenance or overload returning 503, or a long-running upstream operation timing out at the gateway returning 504.
Common situations: Service deployments/maintenance windows, traffic spikes, or intermittent gateway timeouts on large file uploads.
Understand the failure class
- HTTP status errors: handling 4xx and 5xx responses — how to handle 4xx and 5xx responses properly.
Related errors
- Service unavailable: ${text}
- Rate limit exceeded: {msg}
- HTTP {status_code}: {message}
- Either fileUrl or filePath is required.
- OCR result item is missing result.ocrResults.
AI-assisted analysis of PaddlePaddle/PaddleOCR@2661c7c0ef (2026-08-14).
Data as JSON: /api/errors/117cb529b99eda13.
Report an issue: GitHub.