BerriAI/litellm · error · ValueError
Voyage API key is required for multimodal embeddings. Set VO
Error message
Voyage API key is required for multimodal embeddings. Set VOYAGE_API_KEY / VOYAGE_AI_API_KEY / VOYAGE_AI_TOKEN or pass `api_key` explicitly.
What it means
Voyage multimodal embeddings (VoyageMultimodalEmbeddingConfig.validate_environment) build an Authorization: Bearer header. The key is taken from the api_key argument or the env chain VOYAGE_API_KEY, VOYAGE_AI_API_KEY, VOYAGE_AI_TOKEN; if all are empty, this ValueError is raised before the request is sent. Multimodal embedding calls need this even when text-only embedding calls elsewhere in the app already work.
Source
Thrown at litellm/llms/voyage/embedding/transformation_multimodal.py:94
def validate_environment(
self,
headers: dict,
model: str,
messages: list[AllMessageValues],
optional_params: dict,
litellm_params: dict,
api_key: str | None = None,
api_base: str | None = None,
) -> dict:
if api_key is None:
api_key = (
get_secret_str("VOYAGE_API_KEY")
or get_secret_str("VOYAGE_AI_API_KEY")
or get_secret_str("VOYAGE_AI_TOKEN")
)
if not api_key:
raise ValueError(
"Voyage API key is required for multimodal embeddings. "
"Set VOYAGE_API_KEY / VOYAGE_AI_API_KEY / VOYAGE_AI_TOKEN "
"or pass `api_key` explicitly."
)
return {"Authorization": f"Bearer {api_key}"}
def _normalize_content_item(self, item: dict[str, Any]) -> dict[str, Any]:
item_type: Final = item.get("type")
if item_type == "image_url":
image_url = item.get("image_url")
if isinstance(image_url, dict):
image_url = image_url.get("url")
if image_url is None:
raise ValueError(
"Voyage multimodal embeddings require a non-empty `image_url`. "
"Got an image content block without a `url`."
)
if isinstance(image_url, str) and image_url.startswith("data:image/"):View on GitHub (pinned to 77b7c6c40c)
Solutions
- Export VOYAGE_API_KEY (or VOYAGE_AI_API_KEY / VOYAGE_AI_TOKEN) in the runtime environment.
- Or pass api_key directly to the embedding call.
- Store the secret in the platform's secret manager and inject it as VOYAGE_API_KEY at startup.
- Add a startup assertion: assert os.environ.get('VOYAGE_API_KEY'), 'VOYAGE_API_KEY missing'.
Example fix
# before
resp = litellm.embedding(
model="voyage-3-multimodal",
input=[{"content": [{"type": "text", "text": "cat"}, {"type": "image_url", "image_url": "https://..."}]}],
)
# -> ValueError: Voyage API key is required for multimodal embeddings...
# after
resp = litellm.embedding(
model="voyage-3-multimodal",
input=[{"content": [{"type": "text", "text": "cat"}, {"type": "image_url", "image_url": "https://..."}]}],
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")
or os.getenv("VOYAGE_AI_TOKEN")
)
if not VOYAGE_KEY:
raise RuntimeError("Voyage multimodal embedding requires VOYAGE_API_KEY")
resp = litellm.embedding(model="voyage-3-multimodal", input=inputs, api_key=VOYAGE_KEY) Type guard
const hasVoyageKey = (env: Record<string, string | undefined>): boolean => Boolean(env.VOYAGE_API_KEY ?? env.VOYAGE_AI_API_KEY ?? env.VOYAGE_AI_TOKEN);
Try / catch
try:
resp = litellm.embedding(model="voyage-3-multimodal", input=inputs)
except ValueError as e:
if "Voyage API key is required" in str(e):
raise RuntimeError("Set VOYAGE_API_KEY for multimodal embeddings") from e
raise Prevention
- Set VOYAGE_API_KEY in every runtime that touches Voyage models, including serverless.
- Fail fast at startup with an env assertion instead of discovering it mid-request.
- Remember multimodal embeddings have their own key check even if text embeddings already work.
When it happens
Trigger: litellm.embedding(model="voyage-3-multimodal", input=[{"content": [...]}]) with no api_key and none of the three Voyage env vars set; using the older VOYAGE_AI_TOKEN name after an env cleanup; serverless functions that do not inherit local shell env.
Common situations: Adding image embedding to an existing text pipeline where the key was only configured for a different provider; typos in env var names; deploying to Vercel/Lambda without migrating the secret.
Related errors
- api_key is required for Volcengine authentication
- Voyage multimodal embeddings require a non-empty `image_url`
- Voyage AI API key is required. Set via `api_key` parameter o
- CohereException - {original_exception.message}
- Volcengine API key is required. Set ARK_API_KEY / VOLCENGINE
AI-assisted analysis of BerriAI/litellm@77b7c6c40c (2026-08-18).
Data as JSON: /api/errors/d377abf4bdc0b1e4.
Report an issue: GitHub.