invoke-ai/InvokeAI · error · UnsafeDownloadURLException
Download URL '{url}' has no host.
Error message
Download URL '{url}' has no host. What it means
After scheme validation, the URL must contain a host. urlsplit().hostname returns None for malformed or host-less URLs, and validate_download_url raises UnsafeDownloadURLException because a download target without a host cannot be resolved or connected to.
Source
Thrown at invokeai/app/util/ssrf.py:204
def validate_download_url(url: str, allow_private_urls: bool = False) -> None:
"""Reject `url` up front if it obviously points somewhere only the server can reach.
Every address the host resolves to must be public — a hostname with both a public and a
loopback record is rejected, because we cannot control which one the HTTP client picks.
An unresolvable host is allowed through to the HTTP client, so that offline test
environments and mocked sessions keep working. That is only safe because the session
from `build_guarded_session()` re-checks the address it actually connects to.
"""
parts = urlsplit(str(url))
if parts.scheme.lower() not in ALLOWED_SCHEMES:
raise UnsafeDownloadURLException(f"Unsupported URL scheme '{parts.scheme}'. Only http and https are allowed.")
host = parts.hostname
if not host:
raise UnsafeDownloadURLException(f"Download URL '{url}' has no host.")
try:
port = parts.port
except ValueError as e:
raise UnsafeDownloadURLException(f"Download URL '{url}' has an invalid port.") from e
if allow_private_urls:
return
for spelling in _host_spellings(host):
literal = _parse_ipv4_literal(spelling)
if literal is not None:
candidates = [literal]
else:
try:
candidates = _resolve(spelling, port)
except (OSError, UnicodeError, ValueError):
continueView on GitHub (pinned to 0b6a024f2f)
Solutions
- Provide a full absolute URL including scheme and host, e.g. https://host/path/file
- Print/inspect the URL string before calling the download API to catch mangling or truncation
- Use a local import path instead of the remote-download API for local files
- Quote URLs passed through shells to avoid stripping the host
Example fix
// before url = 'https:///models/sd15.safetensors' # empty host // after url = 'https://huggingface.co/models/sd15.safetensors'
Defensive patterns
Strategy: validation
Validate before calling
from urllib.parse import urlsplit
def validate_host(url):
if not urlsplit(str(url)).hostname:
raise ValueError(f"URL has no host: {url}") Try / catch
from invokeai.app.util.ssrf import UnsafeDownloadURLException
try:
download(url)
except UnsafeDownloadURLException as e:
if 'has no host' in str(e):
raise ValueError(f"Fix the download URL, it lacks a host: {url}") from e
raise Prevention
- Build download URLs with f-strings including host explicitly
- Never pass relative filesystem paths to the remote download API
- Log the final URL string before calling the download API
When it happens
Trigger: Passing 'https:///path/model.safetensors' (empty authority), a bare path like '/models/foo.safetensors', or a malformed URL whose netloc is stripped; also spaces or invalid characters that break netloc parsing.
Common situations: String concatenation bugs building the URL (missing host segment); relative paths passed where an absolute download URL is required; URLs mangled by shell escaping.
Related errors
- Download URL '{url}' has an invalid port.
- Cannot derive a safe filename for {url} from '{file_name}'
- Unsupported URL scheme '{parts.scheme}'. Only http and https
- only relative download paths accepted
- Invalid image name, potential directory traversal detected
AI-assisted analysis of invoke-ai/InvokeAI@0b6a024f2f (2026-08-29).
Data as JSON: /api/errors/f2dced06f0f8d3a1.
Report an issue: GitHub.