BerriAI/litellm · error · ValueError
Compresr guardrail api_base has no host
Error message
Compresr guardrail api_base has no host
What it means
ValueError from _validate_api_base when the configured Compresr api_base parses to an empty host — urlparse(url).hostname is None (or empty) even though the URL string is non-empty. Typical shapes are 'http://:8080', 'http:///path', or URLs where everything landed in scheme/path. The guardrail refuses to initialize against a hostless target; this is part of the SSRF defense-in-depth checks.
Source
Thrown at litellm/proxy/guardrails/guardrail_hooks/compresr/compresr.py:137
return addr
def _validate_api_base(url: str) -> str:
"""Return ``url`` if it passes basic outbound-target checks, else raise.
Best-effort defense in depth for a mis/maliciously-configured ``api_base``:
rejects non-http(s) schemes and cloud-metadata IPs/hosts (incl. alternate IP
encodings); private ranges are allowed for on-prem deployments. NOT a complete
SSRF control — no DNS resolution, and the shared client follows redirects and
re-resolves DNS (TOCTOU / rebinding); ``api_base`` is trusted operator config,
so this is an accepted limitation.
"""
parsed: Final = urlparse(url)
if parsed.scheme not in ("http", "https"):
raise ValueError(f"Compresr guardrail api_base must be http or https, got scheme={parsed.scheme!r}")
host: Final = (parsed.hostname or "").lower()
if not host:
raise ValueError("Compresr guardrail api_base has no host")
ip_literal: Final = _parse_ip_literal(host)
if host in _BLOCKED_METADATA_HOSTS or (ip_literal is not None and ip_literal in _BLOCKED_METADATA_IPS):
raise ValueError(f"Compresr guardrail api_base {host!r} is a blocked cloud-metadata host")
return url
def _is_str_object_dict(value: object) -> TypeGuard[dict[str, object]]: # guard-ok: isinstance narrows correctly; predicate is trivially correct # fmt: skip
return isinstance(value, dict)
def _is_object_list(value: object) -> TypeGuard[list[object]]: # guard-ok: isinstance narrows correctly; predicate is trivially correct # fmt: skip
return isinstance(value, list)
def _replace_text_in_content(content: object, new_text: str) -> object:
"""Write ``new_text`` back into a ``content`` value, preserving shape.
``str`` content is replaced directly. An all-text part list collapses to aView on GitHub (pinned to 77b7c6c40c)
Solutions
- Set a complete api_base with an explicit host: http://host:port or https://api.compresr.io.
- Sanity-check: urlparse(api_base).hostname must be non-empty before deploying.
- Fix empty COMPRESR_API_BASE env values and restart the proxy.
Example fix
# before litellm_params: guardrail: compresr api_base: http://:8080 # after litellm_params: guardrail: compresr api_base: http://compresr.internal:8080
Defensive patterns
Strategy: validation
Validate before calling
from urllib.parse import urlparse
def has_host(url: str) -> bool:
return bool(urlparse(url).hostname)
assert has_host(cfg_guardrail.get("api_base", "")), "api_base must include a host, e.g. http://compresr.internal:8080" Type guard
from urllib.parse import urlparse
from typing import TypeGuard
def is_url_with_host(value: object) -> TypeGuard[str]:
return isinstance(value, str) and bool(urlparse(value).hostname) Prevention
- Template configs with non-empty host variables (guard against '' producing 'http://').
- Lint all URL-typed config values with urlparse in CI.
- Prefer full example URLs in config templates so deletions of the host are obvious in review.
When it happens
Trigger: api_base values like 'http://' (nothing else), 'http:///v1', 'http://:9000', or malformed strings with stray characters that push the host into other components; also scheme-only values after a bad string substitution in templated configs.
Common situations: Env var COMPRESR_API_BASE accidentally empty-but-prefixed (e.g., 'http://' + empty host); templating producing 'http:///'; copy-paste losing the hostname between slashes.
Understand the failure class
Background: Config validation failed: what "invalid value for {key}" and settings-rejection errors mean across 19 open-source libraries — this error's family across 19 libraries.
Related errors
- Compresr guardrail api_base must be http or https, got schem
- Compresr guardrail api_base {host!r} is a blocked cloud-meta
- Compresr guardrail requires an API key. Set `api_key` in the
- max_bytes_per_call must be >= 0 (0 disables the cap; positiv
- Invalid Triton API base: {api_base}
AI-assisted analysis of BerriAI/litellm@77b7c6c40c (2026-08-18).
Data as JSON: /api/errors/ba743bc977cdd367.
Report an issue: GitHub.