PaddlePaddle/PaddleOCR · error · APIError
HTTP {status_code}: {message}
Error message
HTTP {status_code}: {message} What it means
Raised as APIError by unwrap_api_response() when the response envelope's 'code' field is a non-zero error code (or non-None), or by raise_for_status() for any non-2xx status not mapped to a more specific error (e.g. 404, 500). The message is 'HTTP {status_code}: {message}' or the payload-extracted msg/errorMsg/message. It is the generic catch-all for service-reported failures.
Source
Thrown at paddleocr/_api_client/_core.py:167
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:
raise ResponseFormatError(
"Response data must contain non-empty string 'jobId'."
)
return job_id
def validate_result_json_url(data: dict) -> str:
result_url = data.get("resultUrl")
if not isinstance(result_url, dict):View on GitHub (pinned to 2661c7c0ef)
Solutions
- Inspect the status code and embedded message to classify the failure.
- For 404, verify the job/resource id and the endpoint path.
- For 500 or envelope codes, retry once with backoff; if it repeats, report with the request id.
- Ensure you are on the current package version so envelope handling matches the service.
Defensive patterns
Strategy: try-catch
Try / catch
from paddleocr._api_client.errors import APIError, PaddleOCRAPIError
try:
result = await client.ocr(file_path=p)
except AuthError:
raise
except InvalidRequestError:
raise
except APIError as e: # generic bucket (404/500/envelope codes)
if e.status_code and e.status_code >= 500:
await asyncio.sleep(2) # one retry for server faults
result = await client.ocr(file_path=p)
else:
raise Prevention
- Catch specific subclasses first; use APIError only as the last bucket.
- Persist request ids / job ids so 404/500 reports are actionable.
- Treat 4xx APIError as permanent and 5xx as retryable.
When it happens
Trigger: Envelope-level error codes from the service (code != 0 with a 200 status), or HTTP statuses like 404 (wrong endpoint/job id), 405, or 500 that fall through the specific handlers.
Common situations: Querying a deleted or nonexistent job id (404), server bugs (500), wrong base URL path, or business-rule errors returned inside the envelope code field.
Related errors
- PaddleOCR official API request failed.
- HTTP ${statusCode}: ${text}
- Bad request: {msg}
- Service unavailable: {msg}
- Token is required. Set PADDLEOCR_ACCESS_TOKEN or pass token
AI-assisted analysis of PaddlePaddle/PaddleOCR@2661c7c0ef (2026-08-14).
Data as JSON: /api/errors/bc54161377581ec1.
Report an issue: GitHub.