PaddlePaddle/PaddleOCR · error · RuntimeError

Downloading from {} failed with code {}!

Error message

Downloading from {} failed with code {}!

What it means

RuntimeError from the same download helper when the HTTP request completes but returns a non-200 status code. Unlike connection failures (which are retried), any HTTP error status is fatal immediately: the server answered with 403/404/429/5xx and the download is aborted before any bytes are written.

Source

Thrown at ppocr/utils/network.py:81

            retry_cnt += 1
        else:
            raise RuntimeError(
                "Download from {} failed. " "Retry limit reached".format(url)
            )

        try:
            req = requests.get(url, stream=True)
        except Exception as e:  # requests.exceptions.ConnectionError
            logger.info(
                "Downloading {} from {} failed {} times with exception {}".format(
                    fname, url, retry_cnt + 1, str(e)
                )
            )
            time.sleep(1)
            continue

        if req.status_code != 200:
            raise RuntimeError(
                "Downloading from {} failed with code "
                "{}!".format(url, req.status_code)
            )

        # For protecting download interrupted, download to
        # tmp_file firstly, move tmp_file to save_path
        # after download finished
        tmp_file = save_path + ".tmp"
        total_size = req.headers.get("content-length")
        with open(tmp_file, "wb") as f:
            if total_size:
                with tqdm(total=(int(total_size) + 1023) // 1024) as pbar:
                    for chunk in req.iter_content(chunk_size=1024):
                        f.write(chunk)
                        pbar.update(1)
            else:
                for chunk in req.iter_content(chunk_size=1024):
                    if chunk:

View on GitHub (pinned to 2661c7c0ef)

Solutions

  1. Test the URL directly (curl -I <url>) and read the status: 404 means update PaddleOCR/config to the current model URL; 403/429 usually means throttling — wait and retry or use an alternate mirror.
  2. Upgrade PaddleOCR to the version whose configs carry the corrected URLs.
  3. Pre-download the file manually to save_path so the helper never issues the request.
Defensive patterns

Strategy: retry

Validate before calling

import requests

def check_download_url(url) -> int:
    r = requests.head(url, allow_redirects=True, timeout=10)
    return r.status_code

status = check_download_url(url)
if status != 200:
    raise SystemExit(f'{url} returned HTTP {status}; fix the URL/config or fetch the file manually into {save_path}')

Try / catch

try:
    download(url, save_path)
except RuntimeError as e:
    if 'failed with code 404' in str(e):
        # permanent: the URL is gone — update PaddleOCR/config to the current release URL
        raise
    # 429/5xx are transient: back off and retry
    time.sleep(30)
    download(url, save_path)

Prevention

When it happens

Trigger: Auto-download of a model/dict file where the URL is wrong (404), the bucket requires auth or blocks hotlinks (403), rate limiting (429), or the remote server errors (5xx).

Common situations: Model URLs moved after a PaddleOCR release (old configs pointing at deleted buckets); mistyped custom pretrained_model paths; CDN throttling when many jobs start at once.

Related errors


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