Graphify-Labs/graphify · error · ValueError
Blocked URL scheme '{parsed.scheme}' - only http and https a
Error message
Blocked URL scheme '{parsed.scheme}' - only http and https are allowed. Got: {url!r} What it means
ValueError from validate_url (security.py) when the URL's scheme is not http/https. This is the first tier of graphify's SSRF protection: file://, ftp://, data:, gopher: and everything else is rejected before any DNS or connection work, with the offending URL echoed.
Source
Thrown at graphify/security.py:113
ip.is_private
or ip.is_reserved
or ip.is_loopback
or ip.is_link_local
or ip in _CGN_NETWORK
)
def validate_url(url: str) -> str:
"""Raise ValueError if *url* is not http or https, or targets a private/internal IP.
Blocks file://, ftp://, data:, and any other scheme that could be used
for SSRF or local file access. Also blocks requests to private/reserved
IP ranges (127.x, 10.x, 169.254.x, etc.) and cloud metadata endpoints
to prevent SSRF in cloud environments.
"""
parsed = urllib.parse.urlparse(url)
if parsed.scheme.lower() not in _ALLOWED_SCHEMES:
raise ValueError(
f"Blocked URL scheme '{parsed.scheme}' - only http and https are allowed. "
f"Got: {url!r}"
)
hostname = parsed.hostname
if hostname:
# Block known cloud metadata hostnames
if hostname.lower() in _BLOCKED_HOSTS:
raise ValueError(
f"Blocked cloud metadata endpoint '{hostname}'. "
f"Got: {url!r}"
)
# Resolve hostname and block private/reserved IP ranges
try:
infos = socket.getaddrinfo(hostname, None, socket.AF_UNSPEC, socket.SOCK_STREAM)
for info in infos:
addr = info[4][0]View on GitHub (pinned to 7fe58b0b0f)
Solutions
- Normalize input: if no scheme, deliberately prepend 'https://' before validation - but never blanket-append schemes to untrusted input without review.
- If the file is genuinely local, use local-file APIs instead of the URL fetcher - the block is intentional.
- Reject early in your own UI/config layer with a clear message so users fix the URL at entry time.
Example fix
# before
url = request.form['url'] # user sent 'example.com/page'
validate_url(url) # ValueError: Blocked URL scheme ''
# after - require an explicit scheme, default deliberately
url = request.form['url'].strip()
if '://' not in url:
url = 'https://' + url # only if defaulting is acceptable for your app
url = validate_url(url) Defensive patterns
Strategy: validation
Validate before calling
from urllib.parse import urlparse
def has_allowed_scheme(url: str) -> bool:
return urlparse(url).scheme.lower() in ("http", "https")
if not has_allowed_scheme(url):
raise HTTPBadRequest("URL must start with http:// or https://") Type guard
def is_safe_url(url: str) -> bool:
try:
validate_url(url)
return True
except ValueError:
return False Try / catch
try:
safe = validate_url(url)
except ValueError as exc:
if "Blocked URL scheme" in str(exc):
return bad_request(str(exc)) # user error - surface, do not log as 500
raise Prevention
- Validate URLs at the trust boundary (form/API entry), not deep in fetch code.
- Never relax the scheme allowlist for 'just one' internal scheme - use dedicated local-file paths instead.
- Echo the URL in errors (as this code does) so users can see what was parsed.
When it happens
Trigger: validate_url(url) where urllib.parse.urlparse reports a scheme outside _ALLOWED_SCHEMES (security.py:110-115) - e.g. 'file:///etc/passwd', 'ftp://host/x', 'data:text/html,...', or a scheme-less 'example.com/path' (parsed scheme ''), which also fails since '' is not allowed.
Common situations: User-supplied URLs from tickets/config passed unchecked; copy-paste of paths without the https:// prefix; attempts to point fetchers at local files; protocol-handler confusion from frontend forms that strip the scheme.
Related errors
- Blocked cloud metadata endpoint '{hostname}'. Got: {url!r}
- ingest: {exc}
- Blocked private/internal IP {addr} (resolved from '{hostname
- OLLAMA_BASE_URL points at a link-local/metadata address ({ho
- DNS resolution failed for '{hostname}': {exc}. Got: {url!r}
AI-assisted analysis of Graphify-Labs/graphify@7fe58b0b0f (2026-08-14).
Data as JSON: /api/errors/723914c6273ceadf.
Report an issue: GitHub.