BerriAI/litellm · error · ValueError

api_base is required for hosted_vllm embeddings

Error message

api_base is required for hosted_vllm embeddings

What it means

The HostedVLLM embedding handler's get_complete_url() builds the endpoint from an explicit api_base argument or the HOSTED_VLLM_API_BASE environment variable. Unlike cloud providers, self-hosted vLLM has no default hostname, so if neither is set a ValueError is raised before the request is sent. The final URL gets /embeddings appended if missing.

Solutions

  1. Pass api_base explicitly: litellm.embedding(model='hosted_vllm/<model>', api_base='http://localhost:8001', input=[...])
  2. Or export HOSTED_VLLM_API_BASE=http://localhost:8001 (note the HOSTED_ prefix — VLLM_API_BASE is a different variable)
  3. Point it at the server that actually serves /embeddings (a vLLM instance started with an embedding model), not the chat server
  4. Do not append /embeddings yourself; LiteLLM appends it if missing

Example fix

# before
litellm.embedding(model="hosted_vllm/BAAI/bge-m3", input=["hello"])

# after
litellm.embedding(
    model="hosted_vllm/BAAI/bge-m3",
    api_base="http://localhost:8001",
    input=["hello"],
)
Defensive patterns

Strategy: validation

Validate before calling

import os

VLLM_EMBED_BASE = api_base or os.getenv("HOSTED_VLLM_API_BASE")
if not VLLM_EMBED_BASE:
    raise SystemExit("hosted_vllm embeddings need api_base or HOSTED_VLLM_API_BASE")

Prevention

When it happens

Trigger: litellm.embedding(model='hosted_vllm/<embedding-model>', input=[...]) called without api_base and without HOSTED_VLLM_API_BASE in the environment.

Common situations: Running embeddings against a local/remote vLLM server and forgetting the base URL; setting VLLM_API_BASE instead of HOSTED_VLLM_API_BASE; .env file not loaded in the deployed process; reusing config from a different provider that has a default base.

Related errors


AI-assisted analysis of BerriAI/litellm@77b7c6c40c (2026-08-18). Data as JSON: /api/errors/4086ba7786322798. Report an issue: GitHub.

Appendix: source

Thrown at litellm/llms/hosted_vllm/embedding/transformation.py:82

        # Merge with existing headers (user's headers take priority)
        return {**default_headers, **headers}

    def get_complete_url(
        self,
        api_base: str | None,
        api_key: str | None,
        model: str,
        optional_params: dict,
        litellm_params: dict,
        stream: bool | None = None,
    ) -> str:
        """
        Get the complete URL for Hosted VLLM Embedding API endpoint.
        """
        if api_base is None:
            api_base = get_secret_str("HOSTED_VLLM_API_BASE")
            if api_base is None:
                raise ValueError("api_base is required for hosted_vllm embeddings")

        # Remove trailing slashes
        api_base = api_base.rstrip("/")

        # Ensure the URL ends with /embeddings
        if not api_base.endswith("/embeddings"):
            api_base = f"{api_base}/embeddings"

        return api_base

    def transform_embedding_request(
        self,
        model: str,
        input: AllEmbeddingInputValues,
        optional_params: dict,
        headers: dict,
    ) -> dict:
        """

View on GitHub (pinned to 77b7c6c40c)