hiyouga/LlamaFactory · error · HTTPException

Could not resolve hostname: {parsed_url.hostname}

Error message

Could not resolve hostname: {parsed_url.hostname}

What it means

Raised as HTTP 400 by check_ssrf_url when socket.getaddrinfo raises socket.gaierror — the hostname in the media URL cannot be resolved via DNS. Resolution happens as part of the SSRF check (to test the IP), so DNS failure surfaces here rather than at fetch time.

Source

Thrown at src/llamafactory/api/common.py:92

        if parsed_url.scheme not in ["http", "https"]:
            raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail="Only HTTP/HTTPS URLs are allowed.")

        hostname = parsed_url.hostname
        if not hostname:
            raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail="Invalid URL hostname.")

        ip_info = socket.getaddrinfo(hostname, parsed_url.port)
        ip_address_str = ip_info[0][4][0]
        ip = ipaddress.ip_address(ip_address_str)

        if not ip.is_global:
            raise HTTPException(
                status_code=status.HTTP_403_FORBIDDEN,
                detail="Access to private or reserved IP addresses is not allowed.",
            )

    except socket.gaierror:
        raise HTTPException(
            status_code=status.HTTP_400_BAD_REQUEST, detail=f"Could not resolve hostname: {parsed_url.hostname}"
        )
    except Exception as e:
        raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail=f"Invalid URL: {e}")

View on GitHub (pinned to f28afaf635)

Solutions

  1. Verify the hostname resolves from the API server: `getent hosts <hostname>` / `nslookup <hostname>` on that host.
  2. Fix typos or use an IP/public hostname that both sides can resolve.
  3. For internal-only media, use local paths with ALLOW_LOCAL_FILES or base64 data URLs.
  4. Check the server's /etc/resolv.conf and egress DNS policy if resolution fails globally.

Example fix

# before
url: 'https://exmaple.com/img.png'  # typo
# after
url: 'https://example.com/img.png'
Defensive patterns

Strategy: validation

Validate before calling

import socket
from urllib.parse import urlparse
def host_resolvable(u):
    try:
        socket.getaddrinfo(urlparse(u).hostname, None)
        return True
    except socket.gaierror:
        return False

assert host_resolvable(media_url)

Try / catch

catch (e) { if (e.status === 400 && e.detail?.startsWith('Could not resolve hostname')) { verify DNS from the SERVER, not your laptop; fix or switch to data URL; } throw e; }

Prevention

When it happens

Trigger: Typo'd or expired domains (https://exmaple.com/img.png); internal hostnames not resolvable from the API server's DNS view; DNS outage; URL built from an unconfigured variable.

Common situations: Client machine resolves a VPN-only hostname but the API server cannot; stale links in datasets; air-gapped deployments without outbound DNS.

Understand the failure class

Related errors


AI-assisted analysis of hiyouga/LlamaFactory@f28afaf635 (2026-08-14). Data as JSON: /api/errors/05b1546b19d1ed79. Report an issue: GitHub.