BerriAI/litellm · error · ValueError

Voyage AI API key is required. Set via `api_key` parameter o

Error message

Voyage AI API key is required. Set via `api_key` parameter or `VOYAGE_API_KEY` env var.

What it means

VoyageRerankConfig.validate_environment resolves the key from the api_key argument or the env chain VOYAGE_API_KEY / VOYAGE_AI_API_KEY. If none is found it raises this ValueError while building the Authorization header, so no network call is attempted. Note this rerank path does not check VOYAGE_AI_TOKEN (unlike the multimodal embedding path).

Source

Thrown at litellm/llms/voyage/rerank/transformation.py:144

        rerank_meta: Final = RerankResponseMeta(billed_units=_billed_units, tokens=_tokens)

        return RerankResponse(
            id=_json_response.get("id", f"voyage-rerank-{model}"),
            results=transformed_results,
            meta=rerank_meta,
        )

    def validate_environment(
        self,
        headers: dict,
        model: str,
        api_key: str | None = None,
        optional_params: dict | None = None,
    ) -> dict:
        if api_key is None:
            api_key = get_secret_str("VOYAGE_API_KEY") or get_secret_str("VOYAGE_AI_API_KEY")
        if api_key is None:
            raise ValueError("Voyage AI API key is required. Set via `api_key` parameter or `VOYAGE_API_KEY` env var.")
        return {
            "Authorization": f"Bearer {api_key}",
            "content-type": "application/json",
        }

    def calculate_rerank_cost(
        self,
        model: str,
        custom_llm_provider: str | None = None,
        billed_units: RerankBilledUnits | None = None,
        model_info: ModelInfo | None = None,
    ) -> tuple[float, float]:
        if (
            model_info is None
            or "input_cost_per_token" not in model_info
            or model_info["input_cost_per_token"] is None
            or billed_units is None
        ):

View on GitHub (pinned to 77b7c6c40c)

Solutions

  1. Export VOYAGE_API_KEY (or VOYAGE_AI_API_KEY): export VOYAGE_API_KEY=pa-....
  2. Or pass api_key explicitly to litellm.rerank.
  3. If you only have VOYAGE_AI_TOKEN, also export it as VOYAGE_API_KEY for the rerank path.
  4. In LiteLLM proxy config, set api_key inside the voyage rerank model's litellm_params.

Example fix

# before
result = litellm.rerank(model="voyage/voyage-3-rerank", query=q, documents=docs)
# -> ValueError: Voyage AI API key is required...

# after
result = litellm.rerank(
    model="voyage/voyage-3-rerank",
    query=q,
    documents=docs,
    api_key=os.environ["VOYAGE_API_KEY"],
)
Defensive patterns

Strategy: validation

Validate before calling

import os

VOYAGE_KEY = os.getenv("VOYAGE_API_KEY") or os.getenv("VOYAGE_AI_API_KEY")
if not VOYAGE_KEY:
    raise RuntimeError("Voyage rerank needs VOYAGE_API_KEY (VOYAGE_AI_TOKEN is NOT read on this path)")
result = litellm.rerank(model="voyage/voyage-3-rerank", query=q, documents=docs, api_key=VOYAGE_KEY)

Type guard

const hasVoyageRerankKey = (env: Record<string, string | undefined>): boolean =>
  Boolean(env.VOYAGE_API_KEY ?? env.VOYAGE_AI_API_KEY);

Try / catch

try:
    result = litellm.rerank(model="voyage/voyage-3-rerank", query=q, documents=docs)
except ValueError as e:
    if "Voyage AI API key is required" in str(e):
        raise RuntimeError("Set VOYAGE_API_KEY for rerank calls") from e
    raise

Prevention

When it happens

Trigger: litellm.rerank(model="voyage/voyage-3-rerank", query=..., documents=[...]) with no api_key and no VOYAGE_API_KEY/VOYAGE_AI_API_KEY set; the key stored only under VOYAGE_AI_TOKEN, which this path does not read.

Common situations: Working embedding calls (which accept VOYAGE_AI_TOKEN) followed by a failing rerank call with the same env; fresh CI containers; keys configured in the proxy for chat models but not for the rerank route.

Related errors


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