langchain-ai/langchain · error · ValueError

Failed to resolve hostname '{hostname}': {e}

Error message

Failed to resolve hostname '{hostname}': {e}

What it means

`validate_safe_url` performs DNS resolution (`socket.getaddrinfo`) on the URL's hostname to inspect the resolved IPs; a `socket.gaierror` (name resolution failure) is wrapped in a `ValueError` with the hostname and OS error string. It means the hostname could not be resolved at validation time, before any request is made.

Source

Thrown at libs/core/langchain_core/_security/_ssrf_protection.py:102

    # DNS resolution and IP validation
    try:
        addr_info = socket.getaddrinfo(
            hostname,
            parsed.port or (443 if parsed.scheme == "https" else 80),
            socket.AF_UNSPEC,
            socket.SOCK_STREAM,
        )

        for result in addr_info:
            ip_str: str = result[4][0]  # type: ignore[assignment]
            try:
                _validate_resolved_ip(ip_str, policy)
            except SSRFBlockedError as exc:
                raise ValueError(str(exc)) from exc

    except socket.gaierror as e:
        msg = f"Failed to resolve hostname '{hostname}': {e}"
        raise ValueError(msg) from e
    except OSError as e:
        msg = f"Network error while validating URL: {e}"
        raise ValueError(msg) from e

    return url_str


def is_safe_url(
    url: str | AnyHttpUrl,
    *,
    allow_private: bool = False,
    allow_http: bool = True,
) -> bool:
    """Non-throwing version of `validate_safe_url`."""
    try:
        validate_safe_url(url, allow_private=allow_private, allow_http=allow_http)
    except ValueError:
        return False

View on GitHub (pinned to e32fa9a52e)

Solutions

  1. Verify the hostname resolves in the same environment: `python -c "import socket; print(socket.getaddrinfo('host', 80))"` from the same container/host
  2. Fix the hostname typo or use a fully-qualified domain name / IP literal where appropriate
  3. If offline validation is expected, skip or short-circuit SSRF validation for trusted internal URLs (e.g. `allow_private=True` plus pre-resolved IPs)
  4. Configure DNS in the container/deployment (e.g. `--dns`, CoreDNS, /etc/resolv.conf) so the name resolves

Example fix

# before
safe = validate_safe_url(f"http://{os.environ['WEBHOOK_HOST']}/cb")

# after
host = os.environ['WEBHOOK_HOST']
try:
    socket.gethostbyname(host)
except socket.gaierror:
    raise ValueError(f"WEBHOOK_HOST {host!r} does not resolve; check DNS config")
safe = validate_safe_url(f"http://{host}/cb")
Defensive patterns

Strategy: validation

Validate before calling

import socket

def hostname_resolves(hostname: str) -> bool:
    try:
        socket.getaddrinfo(hostname, 443, type=socket.SOCK_STREAM)
        return True
    except socket.gaierror:
        return False

if not hostname_resolves(parsed.hostname):
    raise ValueError(f"hostname {parsed.hostname!r} unresolvable; fix DNS")

Try / catch

try:
    safe = validate_safe_url(url)
except ValueError as e:
    if 'Failed to resolve hostname' in str(e):
        # config/DNS problem, not a policy block
        handle_dns_misconfig(url, e)
    else:
        raise

Prevention

When it happens

Trigger: Calling `validate_safe_url('http://nonexistent-host.example/x')` where DNS returns NXDOMAIN or SERVFAIL; typo'd hostnames; bare hostnames like `http://myapi/` that only resolve via search domains the process lacks; air-gapped/offline environments where the resolver is unreachable.

Common situations: Offline development machines or containers with no DNS; internal hostnames that resolve in one network but not another; typos in configured webhook/endpoint URLs; IPv6-only resolvers returning errors for AF_UNSPEC queries.

Related errors


AI-assisted analysis of langchain-ai/langchain@e32fa9a52e (2026-08-14). Data as JSON: /api/errors/b03288c63d7efc00. Report an issue: GitHub.