invoke-ai/InvokeAI · error · UnsafeDownloadURLException
Refusing to download from '{host}': it resolves to a non-pub
Error message
Refusing to download from '{host}': it resolves to a non-public address. Set `allow_private_download_urls` in invokeai.yaml to permit downloads from loopback and private-network addresses. What it means
As an SSRF protection, InvokeAI resolves the download URL's host and refuses to connect if the resulting IP is loopback, private, link-local, or otherwise non-public. check_address() raises UnsafeDownloadURLException for such addresses; downloads can be explicitly permitted from private addresses via config.
Source
Thrown at invokeai/app/util/ssrf.py:180
values.append(int(digits, base))
except ValueError:
return None
widths = {1: (32,), 2: (8, 24), 3: (8, 8, 16), 4: (8, 8, 8, 8)}[len(values)]
if any(value >= 1 << width for value, width in zip(values, widths, strict=True)):
return None
address = 0
for value, width in zip(values, widths, strict=True):
address = (address << width) | value
return ipaddress.IPv4Address(address)
def check_address(ip: IpAddress, host: str) -> None:
"""Raise if `ip` is not an address we are willing to connect to."""
if _is_blocked(ip):
logger.warning("Blocked download host %s resolving to non-public address %s", host, ip)
raise UnsafeDownloadURLException(
f"Refusing to download from '{host}': it resolves to a non-public address. "
"Set `allow_private_download_urls` in invokeai.yaml to permit downloads from loopback "
"and private-network addresses."
)
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))
View on GitHub (pinned to 0b6a024f2f)
Solutions
- If the private source is intended, set allow_private_download_urls: true in invokeai.yaml
- Use a public URL for the model download
- Download the model manually into the models directory and import it locally
- Verify DNS resolution of the host; if it unexpectedly resolves private, fix DNS or use the correct public hostname
Example fix
// before (invokeai.yaml) # allow_private_download_urls not set url = 'http://localhost:8080/model.safetensors' # UnsafeDownloadURLException // after (invokeai.yaml) allow_private_download_urls: true
Defensive patterns
Strategy: validation
Validate before calling
import socket, ipaddress
def is_public_host(url):
host = urlparse(url).hostname
for info in socket.getaddrinfo(host, None):
ip = ipaddress.ip_address(info[4][0])
if not ip.is_global:
return False
return True Try / catch
from invokeai.app.util.ssrf import UnsafeDownloadURLException
try:
download(url)
except UnsafeDownloadURLException as e:
if 'non-public address' in str(e):
# either switch to a public URL or set allow_private_download_urls in invokeai.yaml
...
else:
raise Prevention
- Only point downloads at public hosts by default
- Set allow_private_download_urls: true consciously, only for trusted local mirrors
- Prefer importing models from local disk over URL download for internal sources
When it happens
Trigger: Downloading a model from a URL whose hostname resolves to 127.0.0.1, 10.x, 192.168.x, 169.254.x, or any mapped non-public address while allow_private_download_urls is false (default).
Common situations: Pointing InvokeAI at a local mirror/proxy like http://localhost:8080/model.safetensors or an internal network NAS; testing with a local model server; DNS rebinding to a private IP.
Related errors
- only relative download paths accepted
- {reason}
- Cannot derive a safe filename for {url} from '{file_name}'
- Download interrupted. Resume required.
- Unsupported URL scheme '{parts.scheme}'. Only http and https
AI-assisted analysis of invoke-ai/InvokeAI@0b6a024f2f (2026-08-29).
Data as JSON: /api/errors/7f53c9595ea7e540.
Report an issue: GitHub.