oobabooga/textgen · error · ValueError
Could not resolve hostname: {hostname}
Error message
Could not resolve hostname: {hostname} What it means
Raised by _validate_url() when socket.getaddrinfo() raises socket.gaierror while resolving the URL hostname — i.e. DNS lookup failed (NXDOMAIN, no resolver, offline, or malformed host). The guard must resolve the host to check it against private ranges, so an unresolvable name is treated as invalid rather than being passed through to the HTTP client.
Source
Thrown at modules/web_search.py:40
parsed = urlparse(url)
if parsed.scheme not in ('http', 'https'):
raise ValueError(f"Unsupported URL scheme: {parsed.scheme}")
if '@' in parsed.netloc:
raise ValueError("Invalid URL: userinfo (credentials) in URLs is not allowed")
hostname = parsed.hostname
if not hostname:
raise ValueError("No hostname in URL")
# Resolve hostname and check all returned addresses
try:
for family, _, _, _, sockaddr in socket.getaddrinfo(hostname, None):
ip = ipaddress.ip_address(sockaddr[0])
if not ip.is_global:
raise ValueError(f"Access to non-public address {ip} is blocked")
except socket.gaierror:
raise ValueError(f"Could not resolve hostname: {hostname}")
def safe_get(url, headers=None, timeout=10, max_redirects=5):
"""Fetch a URL with SSRF-safe redirect handling. Validates every hop."""
_validate_url(url)
for _ in range(max_redirects):
response = requests.get(url, headers=headers, timeout=timeout, allow_redirects=False)
if response.is_redirect and 'Location' in response.headers:
url = urljoin(url, response.headers['Location'])
_validate_url(url)
else:
return response
raise ValueError(f"Too many redirects (max {max_redirects})")
def get_current_timestamp():
"""Returns the current time in 24-hour format"""View on GitHub (pinned to ed888c71f2)
Solutions
- Verify the hostname with dig/getent hosts <host> from the same machine/container the app runs on.
- Fix typos or use a different mirror for dead domains.
- If in a container, ensure it has working DNS (docker --dns, correct resolv.conf).
- Retry once after a transient resolver blip, but stop and report if it persists.
Defensive patterns
Strategy: retry
Validate before calling
import socket
from urllib.parse import urlparse
def hostname_resolves(url: str) -> bool:
host = urlparse(url).hostname
if not host:
return False
try:
socket.getaddrinfo(host, None)
return True
except socket.gaierror:
return False Try / catch
import socket
for attempt in range(2): # one retry for transient resolver blips
try:
resp = safe_get(url)
break
except ValueError as e:
if 'Could not resolve hostname' in str(e) and attempt == 0:
continue
raise Prevention
- Verify hostnames with getent/dig from the same network namespace before batch fetching.
- Ensure containers/VMs running the app have working DNS.
- Filter dead domains out of crawl lists early instead of retrying them per run.
When it happens
Trigger: Fetching a URL with a typo'd or non-existent domain ('https://exmaple.com'), a host only resolvable on an internal DNS the process cannot reach, running in a sandbox/container without network access, or a transient resolver failure.
Common situations: Typos in hostnames; expired/dead domains in search results or feeds; air-gapped or DNS-restricted containers; VPN split-DNS where the name only resolves inside the VPN but the process runs outside it.
Understand the failure class
- DNS resolution errors: ENOTFOUND and getaddrinfo failures — how hostname lookups fail and how to debug them.
Related errors
- Access to non-public address {ip} is blocked
- Too many redirects (max {max_redirects})
- Invalid URL: backslashes are not allowed
- Unsupported URL scheme: {parsed.scheme}
- No hostname in URL
AI-assisted analysis of oobabooga/textgen@ed888c71f2 (2026-08-15).
Data as JSON: /api/errors/4dc2f81936167b32.
Report an issue: GitHub.