unslothai/unsloth · error · ValueError
Provider base URL is malformed.
Error message
Provider base URL is malformed.
What it means
urlsplit (or its .port/.hostname access) raised ValueError while parsing the base URL — typically an unparseable port like 'https://host:abc/' or other structurally broken URL syntax. The original exception is chained, preserving the parse reason.
Source
Thrown at studio/backend/core/inference/providers.py:881
caller-supplied hostname is resolved far enough to apply the metadata block
to DNS aliases of it; rejecting other private addresses stays opt-in.
Normalization is strip + trailing-slash removal only (what the client did
before), so validating an already-validated URL returns it unchanged.
"""
if not isinstance(base_url, str) or not base_url.strip():
raise ValueError("Provider base URL is required.")
raw = base_url.strip()
if any(char.isspace() or ord(char) < 32 or ord(char) == 127 for char in raw) or "\\" in raw:
raise ValueError("Provider base URL contains invalid characters.")
try:
parts = urlsplit(raw)
port = parts.port
hostname = parts.hostname
except ValueError as exc:
raise ValueError("Provider base URL is malformed.") from exc
scheme = parts.scheme.lower()
if scheme not in ("http", "https"):
raise ValueError("Provider base URL must use http or https.")
# Userinfo stays allowed for gateways behind basic auth; the checks below read
# the parsed hostname, so http://api.openai.com@169.254.169.254/ is caught.
if not hostname:
raise ValueError("Provider base URL must contain a hostname.")
hostname = hostname.rstrip(".")
if _metadata_host(hostname) or _resolves_to_metadata(hostname, port, scheme):
raise ValueError("Cloud metadata endpoints cannot be used as a provider base URL.")
if os.environ.get(_BLOCK_PRIVATE_ENV) == "1":
_reject_non_public(hostname, port, scheme)
return raw.rstrip("/")
View on GitHub (pinned to 203007d190)
Solutions
- Check the port segment — it must be a decimal number in 0-65535.
- Include the scheme and slashes: 'https://host:8080/v1', not 'host:8080/v1'.
- Validate with a URL parser client-side before submitting.
Example fix
# before
validate_provider_base_url("https://api.example.com:v1")
# after
validate_provider_base_url("https://api.example.com/v1") Defensive patterns
Strategy: validation
Validate before calling
from urllib.parse import urlsplit
try:
urlsplit(raw)._hostinfo # raises ValueError on bad port before the API sees it
except ValueError:
reject_early(raw) Type guard
def parses_as_url(raw: str) -> bool:
from urllib.parse import urlsplit
try:
urlsplit(raw).port
return True
except ValueError:
return False Prevention
- Client-side parse-validate URLs before submitting.
- Beware template interpolation emitting literal ':$PORT' when the variable is empty.
When it happens
Trigger: Base URLs like 'https://host:notaport/v1' (non-numeric port), 'https://host:99999/' (out-of-range port), or other urlsplit-invalid syntax.
Common situations: Hand-edited config with a typo in the port; template interpolation producing ':$PORT' literally when the variable is empty; URL fragments missing slashes like 'host:8080/path' parsed as a scheme.
Understand the failure class
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- Provider base URL must contain a hostname.
- Provider base URL hostname could not be resolved.
- Provider base URL points at a private address, which is disa
- Provider base URL is required.
- Provider base URL contains invalid characters.
AI-assisted analysis of unslothai/unsloth@203007d190 (2026-08-15).
Data as JSON: /api/errors/2c3302633c3977ba.
Report an issue: GitHub.