{"record":{"id":"38f0d4e391f9462d","repo":"BerriAI/litellm","slug":"mavvrik-focus-destination-gcs-session-init-missin","errorCode":null,"errorMessage":"Mavvrik FOCUS destination: GCS session init missing Location header","messagePattern":"Mavvrik FOCUS destination: GCS session init missing Location header","errorType":"exception","errorClass":"RuntimeError","httpStatus":null,"severity":"error","filePath":"litellm/integrations/focus/destinations/mavvrik_destination.py","lineNumber":195,"sourceCode":"        metadata: Final = b'{\"contentEncoding\":\"gzip\",\"contentDisposition\":\"attachment\"}'\n        init_resp: Final = await self._http.client.request(\n            method=\"POST\",\n            url=signed_url,\n            headers={\n                \"Content-Type\": \"application/gzip\",\n                \"x-goog-resumable\": \"start\",\n            },\n            content=metadata,\n            timeout=30.0,\n        )\n        if init_resp.status_code not in (200, 201):\n            raise RuntimeError(\n                f\"Mavvrik FOCUS destination: GCS session init failed ({init_resp.status_code}): {init_resp.text[:400]}\"\n            )\n\n        session_uri: Final = init_resp.headers.get(\"Location\")\n        if not session_uri:\n            raise RuntimeError(\"Mavvrik FOCUS destination: GCS session init missing Location header\")\n        _validate_gcs_url(session_uri, \"session URI\")\n\n        verbose_logger.debug(\n            \"Mavvrik FOCUS destination: GCS session started, uploading %d gzip bytes in %d chunk(s)\",\n            total,\n            max(1, -(-total // _GCS_CHUNK_SIZE)),  # ceiling division\n        )\n\n        # Step 2: upload in chunks; cancel session on any failure to avoid\n        # lingering GCS sessions (they stay open for ~1 week otherwise).\n        offset = 0\n        try:\n            while offset < total:\n                chunk = gzip_bytes[offset : offset + _GCS_CHUNK_SIZE]\n                chunk_end = offset + len(chunk) - 1\n                is_final = (offset + len(chunk)) >= total\n                content_range = f\"bytes {offset}-{chunk_end}/{total}\" if is_final else f\"bytes {offset}-{chunk_end}/*\"\n                expected_statuses = {200, 201} if is_final else {308}","sourceCodeStart":177,"sourceCodeEnd":213,"githubUrl":"https://github.com/BerriAI/litellm/blob/6c2dcb801bf2b75c18f1bb24140e7cf57465cc4d/litellm/integrations/focus/destinations/mavvrik_destination.py#L177-L213","documentation":"A successful GCS resumable-upload session init (200/201) must return the session URI in the Location response header. If the header is absent or empty, the destination cannot proceed with chunked upload and raises. The session URI is subsequently validated to be an https GCS endpoint (errors 409/410).","triggerScenarios":"GCS (or an intermediary) returns 200 to the x-goog-resumable start POST but omits the Location header — e.g. a proxy stripping redirect/Location headers, or an API-gateway response that doesn't forward GCS headers.","commonSituations":"Corporate proxies or service meshes (Envoy/ISTIO with header rewriting) stripping Location; rarely a GCS API anomaly. Pure direct-to-storage.googleapis.com traffic virtually never hits this.","solutions":["Check for intercepting proxies on the egress path and ensure the Location header is passed through unmodified.","Retry the delivery — a fresh signed URL and session init may succeed.","Verify the client hits storage.googleapis.com directly (no transparent rewriting) by dumping response headers in a manual test.","Report to LiteLLM/Mavvrik if it persists with no proxy in the path."],"exampleFix":null,"handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"try:\n    await mavvrik_dest.deliver(content=csv, time_window=tw, filename=\"f.csv\")\nexcept RuntimeError as e:\n    if \"missing Location header\" in str(e):\n        # likely a header-stripping proxy or transient GCS anomaly; a new session usually works\n        await asyncio.sleep(5)\n        await mavvrik_dest.deliver(content=csv, time_window=tw, filename=\"f.csv\")\n    else:\n        raise","preventionTips":["Ensure egress proxies/meshes forward the Location response header from storage.googleapis.com.","Test the full upload path (init → Location → chunk) in staging through the same network path as production."],"tags":["focus","mavvrik","gcs","http-headers","proxy","network"],"backgroundTag":null,"analyzedSha":"6c2dcb801bf2b75c18f1bb24140e7cf57465cc4d","analyzedAt":"2026-08-15T07:12:03.035Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}