BerriAI/litellm · error · SSRFError
URL scheme '{parsed.scheme}' is not allowed
Error message
URL scheme '{parsed.scheme}' is not allowed What it means
Raised by litellm's SSRF validator (validate_url) when a user-supplied URL's scheme is not in the allowed set (http/https only, per _ALLOWED_SCHEMES). Before doing any DNS resolution or IP validation, litellm restricts fetchable URLs to plain web schemes, so schemes like file://, ftp://, gopher://, or javascript:// are rejected outright. This is a security control protecting the proxy from being used to reach non-web resources.
Source
Thrown at litellm/litellm_core_utils/url_utils.py:265
validated, not the hostname that could rebind. Callers should also disable
follow_redirects to prevent redirect-based SSRF bypasses.
Args:
url: The user-supplied URL to validate.
Returns:
Tuple of (rewritten_url, host_header).
The rewritten URL has the hostname replaced with the validated IP.
The host_header value should be sent as the Host header.
Raises:
SSRFError: If the URL scheme is invalid or the hostname resolves
to a private/internal IP address.
"""
parsed: Final = urlparse(url)
if parsed.scheme not in _ALLOWED_SCHEMES:
raise SSRFError(f"URL scheme '{parsed.scheme}' is not allowed")
hostname: Final = parsed.hostname
if not hostname:
raise SSRFError("URL has no hostname")
port: Final = parsed.port
default_port: Final = _default_port_for_scheme(parsed.scheme)
effective_port: Final = port if port is not None else default_port
host_header: Final = _format_host_header(hostname, effective_port, default_port)
is_allowlisted: Final = _is_host_allowlisted(hostname, effective_port)
# Resolve hostname and validate ALL addresses
try:
addrinfo: Final = socket.getaddrinfo(hostname, effective_port, proto=socket.IPPROTO_TCP)
except socket.gaierror as e:
raise SSRFError(f"DNS resolution failed for '{hostname}': {e}")
View on GitHub (pinned to 6c2dcb801b)
Solutions
- Change the URL to use http:// or https://.
- If the scheme came from user input, validate/normalize it before passing it into litellm (urlparse(url).scheme in {'http','https'}).
- For WebSocket endpoints, check whether the integration expects the http(s) upgrade form rather than ws://.
- Strip or quote a leading path like 'C:\...' that is being misparsed as a scheme.
Example fix
# before resp = safe_get(client, "ftp://files.example.com/data.csv") # after resp = safe_get(client, "https://files.example.com/data.csv")
Defensive patterns
Strategy: validation
Validate before calling
from urllib.parse import urlparse
def is_http_url(url: str) -> bool:
return urlparse(url).scheme in {"http", "https"} and bool(urlparse(url).hostname) Type guard
def is_http_url(url) -> bool:
try:
p = urlparse(url)
except Exception:
return False
return p.scheme in {"http", "https"} Try / catch
from litellm.litellm_core_utils.url_utils import SSRFError
try:
resp = safe_get(client, url)
except SSRFError as e:
return bad_request(f"URL rejected: {e}") Prevention
- Validate scheme at input boundaries with urlparse before handing URLs to litellm.
- Reject ws://, ftp://, file:// and bare hostnames in user URL fields.
- Return 400s for scheme violations so users can self-correct.
When it happens
Trigger: Calling validate_url / safe_get / async_safe_get with a URL whose scheme is anything other than http or https — e.g. passing 'file:///etc/passwd', 'ftp://host/file', or a malformed URL where urlparse extracts an unexpected scheme (e.g. 'gopher://127.0.0.1:70').
Common situations: Users configuring api_base or a user-supplied URL field (e.g. file fetch, media URL, MCP/OAuth callback) with a non-HTTP scheme; accidentally including a Windows drive letter ('C:\path') that urlparse reads as scheme 'c'; copy-paste of URLs with custom schemes like 'unix://' or 'ws://'.
Related errors
- {field_name} cannot be a dot path segment
- MAVVRIK_API_ENDPOINT host must be a Mavvrik domain (e.g. htt
- Mavvrik FOCUS destination: {label} must be a GCS endpoint (s
- URL has no hostname
- URL scheme is not allowed
AI-assisted analysis of BerriAI/litellm@6c2dcb801b (2026-08-15).
Data as JSON: /api/errors/7dcaa5e975877433.
Report an issue: GitHub.