{"record":{"id":"411684a5fc5cbf61","repo":"BerriAI/litellm","slug":"no-addresses-found-for-hostname","errorCode":null,"errorMessage":"No addresses found for '{hostname}'","messagePattern":"No addresses found for '(.+?)'","errorType":"exception","errorClass":"SSRFError","httpStatus":null,"severity":"error","filePath":"litellm/litellm_core_utils/url_utils.py","lineNumber":285,"sourceCode":"    hostname: Final = parsed.hostname\n    if not hostname:\n        raise SSRFError(\"URL has no hostname\")\n\n    port: Final = parsed.port\n    default_port: Final = _default_port_for_scheme(parsed.scheme)\n    effective_port: Final = port if port is not None else default_port\n    host_header: Final = _format_host_header(hostname, effective_port, default_port)\n\n    is_allowlisted: Final = _is_host_allowlisted(hostname, effective_port)\n\n    # Resolve hostname and validate ALL addresses\n    try:\n        addrinfo: Final = socket.getaddrinfo(hostname, effective_port, proto=socket.IPPROTO_TCP)\n    except socket.gaierror as e:\n        raise SSRFError(f\"DNS resolution failed for '{hostname}': {e}\")\n\n    if not addrinfo:\n        raise SSRFError(f\"No addresses found for '{hostname}'\")\n\n    if not is_allowlisted:\n        for family, type_, proto, canonname, sockaddr in addrinfo:\n            resolved_ip = _sockaddr_host(sockaddr)\n            if _is_blocked_ip(resolved_ip):\n                raise SSRFError(\n                    f\"URL targets a blocked address ({resolved_ip}). \"\n                    \"If this is a legitimate internal service, add the host \"\n                    \"to `user_url_allowed_hosts` in general_settings.\"\n                )\n\n    # For HTTPS with SSL verification enabled, TLS certificate validation\n    # binds the connection to the hostname — DNS rebinding can't redirect\n    # to a different server because the cert wouldn't match.\n    # When SSL verification is disabled, this defense doesn't apply, so\n    # we rewrite to the validated IP like HTTP.\n    ssl_verify: Final = getattr(litellm, \"ssl_verify\", True)\n    if parsed.scheme == \"https\" and ssl_verify is not False:","sourceCodeStart":267,"sourceCodeEnd":303,"githubUrl":"https://github.com/BerriAI/litellm/blob/6c2dcb801bf2b75c18f1bb24140e7cf57465cc4d/litellm/litellm_core_utils/url_utils.py#L267-L303","documentation":"Raised by litellm's SSRF validator when getaddrinfo returns successfully but with an empty address list for the hostname — a rare result meaning the resolver produced no usable addresses. It fails closed because there is no IP to validate against the SSRF blocklist. Most resolvers raise gaierror instead of returning empty, so seeing this usually indicates a custom/mock resolver or an unusual NSS configuration.","triggerScenarios":"validate_url() on a hostname where getaddrinfo returns [] — e.g. a monkeypatched resolver in tests, an NSS/hosts configuration returning zero entries, or an exotic resolver plugin that yields no records for the name.","commonSituations":"Test mocks that stub getaddrinfo to return []; hosts-file entries with unusual formatting; alternative resolver libraries injected via sitecustomize; container DNS returning empty answers for certain query types.","solutions":["Run getaddrinfo manually for the host to see the raw result: python -c \"import socket; print(socket.getaddrinfo('HOST', 443, proto=socket.IPPROTO_TCP))\".","In tests, fix mocks to return at least one (family, type, proto, canonname, (ip, port)) tuple.","Check /etc/hosts and NSS configuration on the host if the empty result reproduces outside tests."],"exampleFix":"# before (test mock returns no addresses)\nsock.getaddrinfo = lambda *a, **k: []\n\n# after\nsock.getaddrinfo = lambda *a, **k: [(2, 1, 6, '', ('93.184.216.34', 443))]","handlingStrategy":"try-catch","validationCode":"import socket\n\ndef has_addresses(hostname: str) -> bool:\n    try:\n        return bool(socket.getaddrinfo(hostname, 443, proto=socket.IPPROTO_TCP))\n    except socket.gaierror:\n        return False","typeGuard":null,"tryCatchPattern":"from litellm.litellm_core_utils.url_utils import SSRFError\n\ntry:\n    validate_url(url)\nexcept SSRFError as e:\n    if \"No addresses found\" in str(e):\n        # resolver env issue, not user input\n        log.error(\"Resolver returned empty answer for %s\", url)\n    raise","preventionTips":["Keep getaddrinfo mocks realistic in tests (return at least one tuple).","Check /etc/hosts and NSS setup when empty answers appear in production.","Alert on this specific message — it should never fire on stock CPython."],"tags":["ssrf","dns","resolver","internal-guard"],"backgroundTag":null,"analyzedSha":"6c2dcb801bf2b75c18f1bb24140e7cf57465cc4d","analyzedAt":"2026-08-15T07:12:03.035Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}