BerriAI/litellm · error · ValueError
MAVVRIK_API_ENDPOINT host must be a Mavvrik domain (e.g. htt
Error message
MAVVRIK_API_ENDPOINT host must be a Mavvrik domain (e.g. https://api.mavvrik.dev/<tenant_id>)
What it means
The second Mavvrik endpoint check parses the https URL's hostname and requires it to end with one of the allowed suffixes: .mavvrik.dev, .mavvrik.ai, or .mavvrik.app. This is an SSRF/typo guard ensuring the API key is only sent to genuine Mavvrik domains.
Source
Thrown at litellm/integrations/focus/destinations/mavvrik_destination.py:36
get_async_httpx_client,
httpxSpecialProvider,
)
from .base import FocusDestination, FocusTimeWindow
_MAVVRIK_ALLOWED_SUFFIXES: Final = (".mavvrik.dev", ".mavvrik.ai", ".mavvrik.app")
# GCS requires intermediate chunks to be a multiple of 256 KB.
# 8 MB gives a good balance between round-trips and memory pressure.
_GCS_CHUNK_SIZE: Final = 8 * 1024 * 1024 # 8 MB
def _validate_api_endpoint(api_endpoint: str) -> None:
if not api_endpoint.startswith("https://"):
raise ValueError("MAVVRIK_API_ENDPOINT must be an HTTPS URL")
hostname: Final = (urlparse(api_endpoint).hostname or "").lower()
if not any(hostname.endswith(suffix) for suffix in _MAVVRIK_ALLOWED_SUFFIXES):
raise ValueError(
"MAVVRIK_API_ENDPOINT host must be a Mavvrik domain (e.g. https://api.mavvrik.dev/<tenant_id>)"
)
def _validate_gcs_url(url: str, label: str) -> None:
parsed: Final = urlparse(url)
if parsed.scheme != "https":
raise ValueError(f"Mavvrik FOCUS destination: {label} must be HTTPS, got scheme '{parsed.scheme}'")
hostname: Final = (parsed.hostname or "").lower()
if not (hostname == "storage.googleapis.com" or hostname.endswith(".storage.googleapis.com")):
raise ValueError(
f"Mavvrik FOCUS destination: {label} must be a GCS endpoint (storage.googleapis.com), got '{hostname}'"
)
class FocusMavvrikDestination(FocusDestination):
"""Upload FOCUS CSV exports to Mavvrik via GCS signed URL."""
View on GitHub (pinned to 6c2dcb801b)
Solutions
- Use an official Mavvrik domain: https://api.mavvrik.dev/<tenant_id> (or .mavvrik.ai / .mavvrik.app).
- Verify the exact tenant URL from the Mavvrik dashboard's connection instructions.
- For mocking in tests, monkeypatch FocusMavvrikDestination or the allowed-suffixes tuple rather than the endpoint value.
Example fix
# before MAVVRIK_API_ENDPOINT=https://metrics.internal.acme.com/tenant # after MAVVRIK_API_ENDPOINT=https://api.mavvrik.dev/acme-tenant
Defensive patterns
Strategy: validation
Validate before calling
from urllib.parse import urlparse
allowed = (".mavvrik.dev", ".mavvrik.ai", ".mavvrik.app")
host = (urlparse(endpoint).hostname or "").lower()
if not any(host.endswith(s) for s in allowed):
raise SystemExit(f"MAVVRIK_API_ENDPOINT host '{host}' is not a Mavvrik domain") Type guard
from urllib.parse import urlparse
def is_mavvrik_domain(url: str) -> bool:
host = (urlparse(url).hostname or "").lower()
return any(host.endswith(s) for s in (".mavvrik.dev", ".mavvrik.ai", ".mavvrik.app")) Try / catch
try:
dest = FocusMavvrikDestination(prefix=p, config=cfg)
except ValueError as e:
if "Mavvrik domain" in str(e):
raise ConfigError(f"Endpoint '{endpoint}' is not an official Mavvrik host") from e
raise Prevention
- Copy the exact tenant endpoint URL from the Mavvrik dashboard connection page.
- Treat domain-check failures as config typos first: check mavvrik spelling.
When it happens
Trigger: Passing a valid https URL whose host is not a Mavvrik domain, e.g. https://api.mavvrik.example.com, https://mavvrik-dev.com/tenant, https://localhost:8080, or https://evil.dev (note: 'evil.dev' fails because suffix matching requires '.mavvrik.dev', not just '.dev').
Common situations: Custom/private Mavvrik deployments on a company domain; typos in the domain (mavvrik vs mavrik); trying to point the destination at a mock/staging server you control.
Related errors
- Mavvrik FOCUS destination: {label} must be a GCS endpoint (s
- MAVVRIK_API_ENDPOINT must be an HTTPS URL
- Mavvrik FOCUS destination: {label} must be HTTPS, got scheme
- MAVVRIK_API_KEY must be provided for Mavvrik FOCUS destinati
- MAVVRIK_API_ENDPOINT must be provided for Mavvrik FOCUS dest
AI-assisted analysis of BerriAI/litellm@6c2dcb801b (2026-08-15).
Data as JSON: /api/errors/2504be3c2fd57a33.
Report an issue: GitHub.