unslothai/unsloth · error · HTTPException
str(exc)
Error message
str(exc)
What it means
A 400 on POST /api/providers whose detail is the ValueError message from validate_provider_base_url. That function only refuses URLs that can never be a real endpoint: non-http(s) scheme, control characters or backslashes, malformed URL, missing hostname, and cloud metadata endpoints (169.254.169.254 and DNS aliases). Plain http, loopback, LAN hosts, odd ports, query strings and basic-auth userinfo are deliberately allowed for local runtimes like Ollama and vLLM.
Source
Thrown at studio/backend/routes/providers.py:226
payload.max_output_tokens,
)
_validate_provider_auth_contract(
info,
encrypted_api_key = payload.encrypted_api_key,
base_url = payload.base_url,
models = payload.models,
updating = False,
)
base_url = payload.base_url or info["base_url"]
# An empty base URL stays allowed (custom/vLLM entries carry none until the
# user fills one in); anything present is checked before a key is decrypted.
if base_url:
try:
base_url = validate_provider_base_url(base_url)
except ValueError as exc:
raise HTTPException(status_code = 400, detail = str(exc)) from None
api_key = resolve_provider_api_key_or_400(None, payload.encrypted_api_key)
provider_id = uuid.uuid4().hex[:16]
if api_key:
credential_secrets.get_or_create_credential_encryption_key()
with current_credential_write(credential):
providers_db.create_provider(
id = provider_id,
provider_type = payload.provider_type,
display_name = payload.display_name,
base_url = base_url,
models = payload.models,
available_models = payload.available_models,
max_output_tokens = payload.max_output_tokens,
)
try:
if api_key:View on GitHub (pinned to 203007d190)
Solutions
- Use a full http:// or https:// URL with a hostname, e.g. http://localhost:11434/v1.
- Remove backslashes and control characters from the URL.
- If you meant to use an internal gateway, use its real http(s) URL — metadata IPs stay blocked by design.
Example fix
# before base_url = "localhost:11434/v1" # no scheme base_url = "https://169.254.169.254" # metadata # after base_url = "http://localhost:11434/v1"
Defensive patterns
Strategy: validation
Validate before calling
function isValidBaseUrl(u) {
try {
const parsed = new URL(u);
if (!/^https?:$/.test(parsed.protocol)) return false;
if (!parsed.hostname) return false;
if (/\\|\s|[\x00-\x1f\x7f]/.test(u)) return false;
if (parsed.hostname === "169.254.169.254" || parsed.hostname.endsWith(".169.254.169.254")) return false;
return true;
} catch { return false; }
}
if (base_url && !isValidBaseUrl(base_url)) throw new Error("base_url must be a full http(s) URL with a hostname"); Try / catch
try { await createProvider(body); } catch (e) { if (e.status === 400 && /base URL/i.test(e.detail)) { showFieldError("base_url", e.detail); return; } throw e; } Prevention
- Always include the scheme (http:// or https://) in base URLs.
- Local runtimes (Ollama, vLLM, llama.cpp) work with http:// and loopback/LAN hosts — no need to fake https.
- Never target cloud metadata IPs; they are blocked as SSRF protection.
When it happens
Trigger: Creating a provider with base_url like 'ftp://x', 'file:///etc', 'https://', containing backslashes or control chars, or pointing at 169.254.169.254 / a hostname resolving to it (SSRF guard).
Common situations: Copy-pasting a docs URL with a trailing path typo; attempting to reach cloud metadata as an 'endpoint'; Windows-style paths with backslashes; missing scheme.
Related errors
- model load did not reach ready
- unknown family '{name}'
- Refused notebook fetch from {host!r}: not in allowlist {sort
- Cell uses shell metacharacters / interpolation but --no-allo
- load error: {backend.load_progress()}
AI-assisted analysis of unslothai/unsloth@203007d190 (2026-08-15).
Data as JSON: /api/errors/576b7c2a7f13b863.
Report an issue: GitHub.