BerriAI/litellm · error · ValueError

Qdrant url must be provided

Error message

Qdrant url must be provided

What it means

The Qdrant semantic cache needs the URL of a Qdrant server. The constructor resolves it from the qdrant_api_base argument, then the QDRANT_URL environment variable, then QDRANT_API_BASE; if all are empty it raises ValueError. This fails during construction, before the collection-existence check.

Source

Thrown at litellm/caching/qdrant_semantic_cache.py:78

        self.vector_size = vector_size if vector_size is not None else QDRANT_VECTOR_SIZE
        headers = {}

        # check if defined as os.environ/ variable
        if qdrant_api_base:
            if isinstance(qdrant_api_base, str) and qdrant_api_base.startswith("os.environ/"):
                qdrant_api_base = get_secret_str(qdrant_api_base)
        if qdrant_api_key:
            if isinstance(qdrant_api_key, str) and qdrant_api_key.startswith("os.environ/"):
                qdrant_api_key = get_secret_str(qdrant_api_key)

        qdrant_api_base = qdrant_api_base or os.getenv("QDRANT_URL") or os.getenv("QDRANT_API_BASE")
        qdrant_api_key = qdrant_api_key or os.getenv("QDRANT_API_KEY")
        headers = {"Content-Type": "application/json"}
        if qdrant_api_key:
            headers["api-key"] = qdrant_api_key

        if qdrant_api_base is None:
            raise ValueError("Qdrant url must be provided")

        self.qdrant_api_base = qdrant_api_base
        self.qdrant_api_key = qdrant_api_key
        print_verbose(f"qdrant semantic-cache qdrant_api_base: {self.qdrant_api_base}")

        self.headers = headers

        self.sync_client = _get_httpx_client()
        self.async_client = get_async_httpx_client(llm_provider=httpxSpecialProvider.Caching)

        if quantization_config is None:
            print_verbose("Quantization config is not provided. Default binary quantization will be used.")
        collection_exists: Final = self.sync_client.get(
            url=f"{self.qdrant_api_base}/collections/{self.collection_name}/exists",
            headers=self.headers,
        )
        if collection_exists.status_code != 200:
            raise ValueError(f"Error from qdrant checking if /collections exist {collection_exists.text}")

View on GitHub (pinned to 6c2dcb801b)

Solutions

  1. Pass qdrant_api_base explicitly, e.g. QdrantSemanticCache(..., qdrant_api_base='https://xyz.cloud.qdrant.io:6333')
  2. Or export QDRANT_URL (or QDRANT_API_BASE) in the environment the process actually runs in: export QDRANT_URL=https://xyz.cloud.qdrant.io:6333
  3. Verify with print(os.getenv('QDRANT_URL')) in the same process to rule out env-propagation issues

Example fix

# before
QDRANT_API_BASE  # typo / unset
cache = QdrantSemanticCache(collection_name='c', similarity_threshold=0.8)

# after
cache = QdrantSemanticCache(
    collection_name='c',
    similarity_threshold=0.8,
    qdrant_api_base='https://xyz.cloud.qdrant.io:6333',
    qdrant_api_key='your-key',
)
Defensive patterns

Strategy: validation

Validate before calling

import os

qdrant_url = cfg.get('qdrant_api_base') or os.getenv('QDRANT_URL') or os.getenv('QDRANT_API_BASE')
if not qdrant_url:
    raise ValueError('Set qdrant_api_base or the QDRANT_URL env var before enabling qdrant semantic caching')

Prevention

When it happens

Trigger: Constructing QdrantSemanticCache without qdrant_api_base while neither QDRANT_URL nor QDRANT_API_BASE is set in the process environment (common in fresh deploy targets, CI, or containers where the env var was set in a different shell).

Common situations: Env var set locally but not in the deployment (Docker/Kubernetes env not injected); typo in the variable name (e.g. QDRANT_ENDPOINT); value stored only in a .env file that the running process never loaded.

Related errors


AI-assisted analysis of BerriAI/litellm@6c2dcb801b (2026-08-15). Data as JSON: /api/errors/2970fa91389b90d0. Report an issue: GitHub.