BerriAI/litellm · error · AzureOpenAIError
OIDC token could not be retrieved from secret manager.
Error message
OIDC token could not be retrieved from secret manager.
What it means
After client/tenant IDs are resolved, LiteLLM reads the OIDC token via get_secret_str(azure_ad_token). If the value is None — because no azure_ad_token was supplied, or the secret manager lookup returned nothing — it raises AzureOpenAIError 401. This is a guard that the workload-identity assertion JWT must be present before calling the Azure AD token endpoint.
Source
Thrown at litellm/llms/azure/common_utils.py:203
Returns:
`azure_ad_token_access_token` - str
"""
if scope is None:
scope = "https://cognitiveservices.azure.com/.default"
azure_authority_host: Final = os.getenv("AZURE_AUTHORITY_HOST", "https://login.microsoftonline.com")
azure_client_id = azure_client_id or os.getenv("AZURE_CLIENT_ID")
azure_tenant_id = azure_tenant_id or os.getenv("AZURE_TENANT_ID")
if azure_client_id is None or azure_tenant_id is None:
raise AzureOpenAIError(
status_code=422,
message="AZURE_CLIENT_ID and AZURE_TENANT_ID must be set",
)
oidc_token: Final = get_secret_str(azure_ad_token)
if oidc_token is None:
raise AzureOpenAIError(
status_code=401,
message="OIDC token could not be retrieved from secret manager.",
)
azure_ad_token_cache_key: Final = json.dumps(
{
"azure_client_id": azure_client_id,
"azure_tenant_id": azure_tenant_id,
"azure_authority_host": azure_authority_host,
"oidc_token": oidc_token,
}
)
azure_ad_token_access_token = azure_ad_cache.get_cache(azure_ad_token_cache_key)
if azure_ad_token_access_token is not None:
return azure_ad_token_access_token
client: Final = litellm.module_level_clientView on GitHub (pinned to 6c2dcb801b)
Solutions
- Pass a real, non-empty OIDC/JWT string as azure_ad_token when calling LiteLLM.
- If using secret-manager references, verify the secret exists and the manager is configured: check get_secret() resolves it (e.g. os.environ for env-based secrets, or your secret backend).
- In containers/pods, confirm the workload-identity token file (e.g. AZURE_FEDERATED_TOKEN_FILE) is mounted and your code reads it into azure_ad_token before calling LiteLLM.
- If you meant to use key auth, drop azure_ad_token and pass api_key instead.
Example fix
# before
resp = litellm.completion(model="azure/<dep>", messages=msgs, azure_ad_token="") # empty -> None
# after
oidc = requests.get(
"http://169.254.169.254/metadata/identity/oauth2/token",
params={"api-version": "2019-08-01", "resource": "https://cognitiveservices.azure.com"},
headers={"Metadata": "true"},
).json()["access_token"]
resp = litellm.completion(model="azure/<dep>", messages=msgs, azure_ad_token=oidc) Defensive patterns
Strategy: validation
Validate before calling
import os
def resolve_oidc_token(token_or_key: str | None) -> str:
# resolve like LiteLLM: treat a non-JWT value as an env/secret key
value = os.getenv(token_or_key) if token_or_key and not token_or_key.startswith("ey") else token_or_key
if not value:
raise AuthError("OIDC token missing: fetch it from the workload identity endpoint first")
return value Type guard
def is_valid_oidc_token(t: object) -> bool:
return isinstance(t, str) and t.count(".") == 2 and len(t) > 100 Try / catch
try:
resp = litellm.completion(..., azure_ad_token=oidc)
except AzureOpenAIError as e:
if e.status_code == 401 and "OIDC token" in str(e):
oidc = fetch_fresh_oidc() # metadata endpoint
resp = litellm.completion(..., azure_ad_token=oidc)
else:
raise Prevention
- Fetch the OIDC token immediately before each call chain; never cache longer than its TTL.
- If using secret-manager references, test resolution in CI with the same backend.
- Treat empty-string tokens as missing in your own layer (get_secret_str does).
When it happens
Trigger: AZURE_CLIENT_ID and AZURE_TENANT_ID are set but azure_ad_token is None/empty, or the value passed is a secret-manager key (e.g. 'azure/oidc/token') that the configured secret manager cannot resolve. Also triggered by passing an empty string, which get_secret_str normalizes to None.
Common situations: Federated credentials setup where the app fetches the OIDC token lazily but LiteLLM is called before it is available; secret deleted/rotated in AWS/GCP secret manager while the key reference stayed in config; passing the literal token in one environment but only the key name in another.
Related errors
- AZURE_CLIENT_ID and AZURE_TENANT_ID must be set
- AZURE_SENTINEL_CLIENT_SECRET or AZURE_CLIENT_SECRET is requi
- api_key is required for Azure AI Speech transcription.
- {req_token.text}
- Azure AD token must be a string, got {type(token)}
AI-assisted analysis of BerriAI/litellm@6c2dcb801b (2026-08-15).
Data as JSON: /api/errors/7c96308aba2ae317.
Report an issue: GitHub.