{"record":{"id":"2462300341391360","repo":"BerriAI/litellm","slug":"error-from-qdrant-checking-if-collections-exist","errorCode":null,"errorMessage":"Error from qdrant checking if /collections exist {collection_exists.text}","messagePattern":"Error from qdrant checking if /collections exist (.+?)","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"litellm/caching/qdrant_semantic_cache.py","lineNumber":96,"sourceCode":"            raise ValueError(\"Qdrant url must be provided\")\n\n        self.qdrant_api_base = qdrant_api_base\n        self.qdrant_api_key = qdrant_api_key\n        print_verbose(f\"qdrant semantic-cache qdrant_api_base: {self.qdrant_api_base}\")\n\n        self.headers = headers\n\n        self.sync_client = _get_httpx_client()\n        self.async_client = get_async_httpx_client(llm_provider=httpxSpecialProvider.Caching)\n\n        if quantization_config is None:\n            print_verbose(\"Quantization config is not provided. Default binary quantization will be used.\")\n        collection_exists: Final = self.sync_client.get(\n            url=f\"{self.qdrant_api_base}/collections/{self.collection_name}/exists\",\n            headers=self.headers,\n        )\n        if collection_exists.status_code != 200:\n            raise ValueError(f\"Error from qdrant checking if /collections exist {collection_exists.text}\")\n\n        if collection_exists.json()[\"result\"][\"exists\"]:\n            collection_details = self.sync_client.get(\n                url=f\"{self.qdrant_api_base}/collections/{self.collection_name}\",\n                headers=self.headers,\n            )\n            self.collection_info = collection_details.json()\n            print_verbose(f\"Collection already exists.\\nCollection details:{self.collection_info}\")\n            self._ensure_cache_key_payload_index()\n        else:\n            quantization_params: dict[str, Any]\n            if quantization_config is None or quantization_config == \"binary\":\n                quantization_params = {\n                    \"binary\": {\n                        \"always_ram\": False,\n                    }\n                }\n            elif quantization_config == \"scalar\":","sourceCodeStart":78,"sourceCodeEnd":114,"githubUrl":"https://github.com/BerriAI/litellm/blob/6c2dcb801bf2b75c18f1bb24140e7cf57465cc4d/litellm/caching/qdrant_semantic_cache.py#L78-L114","documentation":"During construction the cache makes a synchronous HTTP GET to {qdrant_api_base}/collections/{collection_name}/exists; if the response status is not 200 it raises ValueError embedding the response body. Root causes range from auth failure (401/403), wrong URL, non-existent collection with permission errors, to a non-Qdrant server answering at that URL.","triggerScenarios":"QdrantSemanticCache construction with an invalid or expired qdrant_api_key (401), a qdrant_api_base pointing at a proxy/gateway that returns 4xx/5xx, a Qdrant Cloud instance on a paused/free tier, or a URL with a wrong port.","commonSituations":"Rotated or mistyped Qdrant API key; pointing at the Qdrant gRPC port (6334) instead of the REST port (6333); corporate proxy intercepting the request; Qdrant Cloud cluster paused or deleted.","solutions":["Read the embedded response text in the message — it names the actual HTTP problem (401 vs 404 vs 502)","Reproduce the call manually: curl -H 'api-key: $QDRANT_API_KEY' $QDRANT_URL/collections/<name>/exists and fix whatever it reports","Confirm the URL uses the REST port (default 6333 for self-hosted) and the api-key header is valid","If a proxy sits in front of Qdrant, allowlist the /collections/* paths"],"exampleFix":"# before\ncache = QdrantSemanticCache(collection_name='c', similarity_threshold=0.8,\n                           qdrant_api_base='https://xyz.cloud.qdrant.io:6334')  # gRPC port\n\n# after\ncache = QdrantSemanticCache(collection_name='c', similarity_threshold=0.8,\n                           qdrant_api_base='https://xyz.cloud.qdrant.io:6333')  # REST port","handlingStrategy":"try-catch","validationCode":"import httpx\n\ndef qdrant_reachable(base: str, key: str | None, collection: str) -> bool:\n    headers = {'Content-Type': 'application/json', **({'api-key': key} if key else {})}\n    try:\n        r = httpx.get(f'{base}/collections/{collection}/exists', headers=headers, timeout=5)\n        return r.status_code == 200\n    except httpx.HTTPError:\n        return False","typeGuard":null,"tryCatchPattern":"try:\n    cache = QdrantSemanticCache(collection_name='c', similarity_threshold=0.8,\n                               qdrant_api_base=base, qdrant_api_key=key)\nexcept ValueError as e:\n    # message embeds the Qdrant response body — log it for diagnosis\n    logger.error('Qdrant cache init failed: %s', e)\n    raise","preventionTips":["Health-check the /collections/<name>/exists endpoint in startup probes","Keep Qdrant REST port (6333) and API key in a secret manager and validate rotation","Log the response body embedded in the ValueError — it contains the true HTTP error"],"tags":["qdrant","http","authentication","network","semantic-cache"],"backgroundTag":null,"analyzedSha":"6c2dcb801bf2b75c18f1bb24140e7cf57465cc4d","analyzedAt":"2026-08-15T07:12:03.035Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}