docling-project/docling · error · ValueError

Cannot resolve hostname: {hostname}

Error message

Cannot resolve hostname: {hostname}

What it means

ValueError raised when the URL's hostname is not a literal IP and socket.gethostbyname() fails with gaierror/herror — i.e. DNS cannot resolve it. Part of validate_url_safety; the original socket error is chained. Resolution happens before the restricted-IP check so that hostnames pointing at internal ranges are still caught.

Source

Thrown at docling/backend/utils/image_resource_loader.py:63

    Raises:
        ValueError: If the URL has no hostname, the hostname cannot be
            resolved, or it resolves to a restricted (non-global) IP address.
    """
    parsed = urlparse(url)
    hostname = parsed.hostname

    if not hostname:
        raise ValueError("URL must contain a valid hostname")

    try:
        ip = ipaddress.ip_address(hostname)
    except ValueError:
        try:
            ip_str = socket.gethostbyname(hostname)
            ip = ipaddress.ip_address(ip_str)
        except (socket.gaierror, socket.herror) as e:
            raise ValueError(f"Cannot resolve hostname: {hostname}") from e

    if not (
        ip.is_global
        and not (
            ip.is_private
            or ip.is_loopback
            or ip.is_link_local
            or ip.is_reserved
            or ip.is_multicast
            or ip.is_unspecified
        )
    ):
        raise ValueError(f"Access to restricted IP address not allowed: {ip}")


class ImageResourceLoader:
    """Resolve and load image resources for declarative document backends.

View on GitHub (pinned to 61d76f1ff3)

Solutions

  1. Check resolution where docling runs: dig +short example.com or python -c "import socket; socket.gethostbyname('example.com')".
  2. If offline, disable remote fetch and pre-download images (or enable_local_fetch with a local base_path).
  3. Fix typo'd hostnames in the source document.
  4. Catch ValueError to skip unresolvable images and continue conversion.

Example fix

# before
loader.load_image_data('https://exmaple.com/logo.png', base)  # Cannot resolve hostname

# after
import socket
host = 'exmaple.com'
try:
    socket.gethostbyname(host)
    data = loader.load_image_data(f'https://{host}/logo.png', base)
except socket.gaierror:
    data = None  # skip broken image
Defensive patterns

Strategy: validation

Validate before calling

import socket
from urllib.parse import urlparse
host = urlparse(url).hostname
if host:
    try:
        socket.gethostbyname(host)
    except (socket.gaierror, socket.herror):
        raise ValueError(f'cannot resolve {host}; skip or fix URL')

Try / catch

try:
    data = loader.load_image_data(src, base)
except ValueError as e:
    if 'Cannot resolve hostname' in str(e):
        data = None  # degrade gracefully, skip image
    else:
        raise

Prevention

When it happens

Trigger: Document references an image at a hostname like https://nonexistent.invalid/x.png (NXDOMAIN), a name only resolvable on an internal DNS the runner lacks, or a typo like 'https://exmaple.com/logo.png'.

Common situations: Converting HTML crawled from intranets on machines without that DNS; offline environments blocking outbound DNS; expired external image hosts.

Related errors


AI-assisted analysis of docling-project/docling@61d76f1ff3 (2026-08-14). Data as JSON: /api/errors/99a88205a816eaa2. Report an issue: GitHub.