{"record":{"id":"82e34683d8a2db10","repo":"BerriAI/litellm","slug":"mavvrik-api-endpoint-must-be-an-https-url","errorCode":null,"errorMessage":"MAVVRIK_API_ENDPOINT must be an HTTPS URL","messagePattern":"MAVVRIK_API_ENDPOINT must be an HTTPS URL","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"litellm/integrations/focus/destinations/mavvrik_destination.py","lineNumber":33,"sourceCode":"from litellm._logging import verbose_logger\nfrom litellm.llms.custom_httpx.http_handler import (\n    AsyncHTTPHandler,\n    get_async_httpx_client,\n    httpxSpecialProvider,\n)\n\nfrom .base import FocusDestination, FocusTimeWindow\n\n_MAVVRIK_ALLOWED_SUFFIXES: Final = (\".mavvrik.dev\", \".mavvrik.ai\", \".mavvrik.app\")\n\n# GCS requires intermediate chunks to be a multiple of 256 KB.\n# 8 MB gives a good balance between round-trips and memory pressure.\n_GCS_CHUNK_SIZE: Final = 8 * 1024 * 1024  # 8 MB\n\n\ndef _validate_api_endpoint(api_endpoint: str) -> None:\n    if not api_endpoint.startswith(\"https://\"):\n        raise ValueError(\"MAVVRIK_API_ENDPOINT must be an HTTPS URL\")\n    hostname: Final = (urlparse(api_endpoint).hostname or \"\").lower()\n    if not any(hostname.endswith(suffix) for suffix in _MAVVRIK_ALLOWED_SUFFIXES):\n        raise ValueError(\n            \"MAVVRIK_API_ENDPOINT host must be a Mavvrik domain (e.g. https://api.mavvrik.dev/<tenant_id>)\"\n        )\n\n\ndef _validate_gcs_url(url: str, label: str) -> None:\n    parsed: Final = urlparse(url)\n    if parsed.scheme != \"https\":\n        raise ValueError(f\"Mavvrik FOCUS destination: {label} must be HTTPS, got scheme '{parsed.scheme}'\")\n    hostname: Final = (parsed.hostname or \"\").lower()\n    if not (hostname == \"storage.googleapis.com\" or hostname.endswith(\".storage.googleapis.com\")):\n        raise ValueError(\n            f\"Mavvrik FOCUS destination: {label} must be a GCS endpoint (storage.googleapis.com), got '{hostname}'\"\n        )\n\n","sourceCodeStart":15,"sourceCodeEnd":51,"githubUrl":"https://github.com/BerriAI/litellm/blob/6c2dcb801bf2b75c18f1bb24140e7cf57465cc4d/litellm/integrations/focus/destinations/mavvrik_destination.py#L15-L51","documentation":"FocusMavvrikDestination validates the configured Mavvrik API endpoint before any network call. The very first check requires the string to start with 'https://' — anything else (http://, a bare hostname, a typo like htps://) is rejected immediately to prevent sending the API key over plaintext or to an unvalidated host.","triggerScenarios":"Passing api_endpoint='http://api.mavvrik.dev/...' or a scheme-less 'api.mavvrik.dev/tenant' in the mavvrik destination config / MAVVRIK_API_ENDPOINT env var when the destination is constructed.","commonSituations":"Local development endpoints using http; copy-pasting a hostname without the scheme; proxy rewrites stripping the scheme; internal test tenants configured with plain http.","solutions":["Use an https:// URL, e.g. https://api.mavvrik.dev/<tenant_id>.","If testing locally against http, tunnel through an https endpoint (ngrok/tls proxy) — the check is strict by design.","Normalize the value before saving it to config: if not endpoint.startswith('https://'): fix it at the source."],"exampleFix":"# before\nMAVVRIK_API_ENDPOINT=http://api.mavvrik.dev/acme\n\n# after\nMAVVRIK_API_ENDPOINT=https://api.mavvrik.dev/acme","handlingStrategy":"validation","validationCode":"endpoint = os.getenv(\"MAVVRIK_API_ENDPOINT\", \"\")\nif not endpoint.startswith(\"https://\"):\n    raise SystemExit(\"MAVVRIK_API_ENDPOINT must start with https:// — refusing to send API key over plaintext\")","typeGuard":"def is_https(url: str) -> bool:\n    return url.startswith(\"https://\")","tryCatchPattern":"try:\n    dest = FocusMavvrikDestination(prefix=p, config=cfg)\nexcept ValueError as e:\n    if \"HTTPS\" in str(e):\n        raise ConfigError(\"Mavvrik endpoint must be https\") from e\n    raise","preventionTips":["Enforce https in config validation at load time, not at destination construction.","For local testing use an https tunnel; never relax the scheme check."],"tags":["focus","mavvrik","validation","security","configuration"],"backgroundTag":null,"analyzedSha":"6c2dcb801bf2b75c18f1bb24140e7cf57465cc4d","analyzedAt":"2026-08-15T07:12:03.035Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}