{"record":{"id":"8742fb12c0c38e5a","repo":"BerriAI/litellm","slug":"no-upload-url-returned-in-response-headers","errorCode":null,"errorMessage":"No upload URL returned in response headers","messagePattern":"No upload URL returned in response headers","errorType":"exception","errorClass":"Exception","httpStatus":null,"severity":"error","filePath":"litellm/rag/ingestion/gemini_ingestion.py","lineNumber":282,"sourceCode":"        client: Final = get_async_httpx_client(\n            llm_provider=httpxSpecialProvider.RAG,\n            params={\"timeout\": 60.0},\n        )\n        response: Final = await client.post(\n            url,\n            json=request_body,\n            headers=headers,\n        )\n\n        if response.status_code not in [200, 201]:\n            error_msg: Final = f\"Failed to initiate upload: {response.text}\"\n            verbose_logger.error(error_msg)\n            raise Exception(error_msg)\n        verbose_logger.debug(\"Initiate resumable upload response: %s\", response.headers)\n        # Extract upload URL from response headers\n        upload_url: Final = response.headers.get(\"x-goog-upload-url\")\n        if not upload_url:\n            raise Exception(\"No upload URL returned in response headers\")\n\n        verbose_logger.debug(\"Got upload URL: %s\", upload_url)\n        return upload_url\n\n    async def _upload_file_content(\n        self,\n        upload_url: str,\n        file_content: bytes,\n    ) -> str:\n        \"\"\"\n        Upload file content to the resumable upload URL.\n\n        Returns:\n            File ID or document name from the response\n        \"\"\"\n        headers: Final = {\n            \"Content-Length\": str(len(file_content)),\n            \"X-Goog-Upload-Offset\": \"0\",","sourceCodeStart":264,"sourceCodeEnd":300,"githubUrl":"https://github.com/BerriAI/litellm/blob/77b7c6c40c0c5aa5fbcb1d6a1825ac39ca8829b8/litellm/rag/ingestion/gemini_ingestion.py#L264-L300","documentation":"Protocol guard after a successful upload-initiation response: the Gemini Files API did not return the X-Goog-Upload-URL header (or it was empty), so there is no destination URL for the file bytes. Usually indicates an API change or an unexpected response shape; the logged headers show what came back.","triggerScenarios":"Thrown at litellm/rag/ingestion/gemini_ingestion.py:282 when the library encounters an invalid state.","commonSituations":"See trigger scenarios.","solutions":["Retry the upload initiation; if persistent, verify the Gemini File Search API version and endpoint."],"exampleFix":null,"handlingStrategy":"validation","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":[],"tags":[],"backgroundTag":null,"analyzedSha":"77b7c6c40c0c5aa5fbcb1d6a1825ac39ca8829b8","analyzedAt":"2026-08-18T11:44:31.656Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}