{"record":{"id":"ce729a16c9ad0efe","repo":"lfnovo/open-notebook","slug":"could-not-resolve-hostname-hostname-for-outbou","errorCode":null,"errorMessage":"Could not resolve hostname '{hostname}' for outbound request.","messagePattern":"Could not resolve hostname '(.+?)' for outbound request\\.","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"open_notebook/utils/url_validation.py","lineNumber":151,"sourceCode":"        )\n\n    hostname = parsed.hostname\n    if not hostname:\n        raise ValueError(\"Invalid URL: hostname could not be determined.\")\n\n    try:\n        ip = ipaddress.ip_address(hostname)\n        _reject_dangerous_ip(ip, hostname)\n        # Already an IP literal — no rewrite / Host / SNI override needed.\n        return PinnedHttpTarget(url=url.strip())\n    except ValueError as ve:\n        if \"Link-local\" in str(ve) or \"Invalid URL\" in str(ve) or \"metadata\" in str(ve):\n            raise\n\n    try:\n        safe_ips = await _resolve_safe_ips(hostname)\n    except socket.gaierror as exc:\n        raise ValueError(\n            f\"Could not resolve hostname '{hostname}' for outbound request.\"\n        ) from exc\n\n    if not safe_ips:\n        raise ValueError(\n            f\"Could not resolve hostname '{hostname}' for outbound request.\"\n        )\n\n    # Prefer IPv4 when available (simpler URL form; same vetted set).\n    pinned_ip = next((ip for ip in safe_ips if \":\" not in ip), safe_ips[0])\n    host_for_url = f\"[{pinned_ip}]\" if \":\" in pinned_ip else pinned_ip\n    # HTTP Host / TLS SNI must be ASCII; IDNA-encode internationalized names.\n    ascii_hostname = hostname.encode(\"idna\").decode(\"ascii\")\n    if parsed.port is not None:\n        netloc = f\"{host_for_url}:{parsed.port}\"\n        host_header = f\"{ascii_hostname}:{parsed.port}\"\n    else:\n        netloc = host_for_url","sourceCodeStart":133,"sourceCodeEnd":169,"githubUrl":"https://github.com/lfnovo/open-notebook/blob/a7de90d38aaf18ee85fd661854d35c11e44613e2/open_notebook/utils/url_validation.py#L133-L169","documentation":"The hostname passed DNS resolution through socket.getaddrinfo but it raised socket.gaierror (name or service not known, or resolver failure). Since the SSRF pinning layer needs at least one IP to vet and pin, an unresolvable host aborts the outbound request. The original gaierror is chained for debugging.","triggerScenarios":"Calling discover_with_config or a connection-test helper with a hostname that doesn't exist (typo like 'api.openai.co'), a resolver outage, or an internal-only DNS name from a machine outside that network.","commonSituations":"Typo'd provider hostname in config; on-prem/Ollama host name only resolvable inside the company VPN; container where the DNS server is unreachable; /etc/hosts entry forgotten when migrating to Docker.","solutions":["Verify the hostname resolves from the same machine/container: `getent hosts <hostname>` or `nslookup <hostname>`","Fix typos in the configured hostname","If the host is internal, run the service where that DNS name resolves (VPN, docker network alias, or compose service name)","Check container DNS settings (docker --dns, compose dns: block) if resolution works on the host but not inside the container"],"exampleFix":"# before\nawait _test_ollama_connection(\"http://ollama-host:11434\")  # name not in this network\n# after (docker-compose service name)\nawait _test_ollama_connection(\"http://ollama:11434\")","handlingStrategy":"try-catch","validationCode":"import socket\n\ndef hostname_resolves(host: str) -> bool:\n    try:\n        socket.getaddrinfo(host, None)\n        return True\n    except socket.gaierror:\n        return False","typeGuard":null,"tryCatchPattern":"try:\n    target = await prepare_pinned_http_target(url, provider)\nexcept ValueError as e:\n    if \"Could not resolve hostname\" in str(e):\n        return {\"status\": \"unreachable\", \"hint\": \"check DNS / VPN / typo\"}\n    raise","preventionTips":["Pre-flight resolve provider hostnames at config-save time","In Docker, reference services by compose service name","Verify VPN connectivity before testing internal endpoints"],"tags":["dns","network","hostname-resolution"],"backgroundTag":"dns-resolution-failure","analyzedSha":"a7de90d38aaf18ee85fd661854d35c11e44613e2","analyzedAt":"2026-08-27T02:39:58.166Z","schemaVersion":2},"datasetVersion":"2026-08-27T03:17:27.898Z"}