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

  1. Inspect the status code and embedded message to classify the failure.
  2. For 404, verify the job/resource id and the endpoint path.
  3. For 500 or envelope codes, retry once with backoff; if it repeats, report with the request id.
  4. 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

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


AI-assisted analysis of PaddlePaddle/PaddleOCR@2661c7c0ef (2026-08-14). Data as JSON: /api/errors/bc54161377581ec1. Report an issue: GitHub.