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 FalseView on GitHub (pinned to e32fa9a52e)
Solutions
- Verify the hostname resolves in the same environment: `python -c "import socket; print(socket.getaddrinfo('host', 80))"` from the same container/host
- Fix the hostname typo or use a fully-qualified domain name / IP literal where appropriate
- If offline validation is expected, skip or short-circuit SSRF validation for trusted internal URLs (e.g. `allow_private=True` plus pre-resolved IPs)
- 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
- Pre-resolve hostnames from config files at startup, not at request time
- Run containers with a working resolver; test with `getent hosts <name>`
- Distinguish resolution failures (gaierror text) from policy blocks in error handling
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
- invalid IP address
- Network error while validating URL: {e}
- private IP range
- blocked CIDR
- localhost address
AI-assisted analysis of langchain-ai/langchain@e32fa9a52e (2026-08-14).
Data as JSON: /api/errors/b03288c63d7efc00.
Report an issue: GitHub.