{"record":{"id":"393ea53c7b339d46","repo":"BerriAI/litellm","slug":"azure-client-id-and-azure-tenant-id-must-be-set","errorCode":null,"errorMessage":"AZURE_CLIENT_ID and AZURE_TENANT_ID must be set","messagePattern":"AZURE_CLIENT_ID and AZURE_TENANT_ID must be set","errorType":"http","errorClass":"AzureOpenAIError","httpStatus":422,"severity":"error","filePath":"litellm/llms/azure/common_utils.py","lineNumber":195,"sourceCode":"    \"\"\"\n    Get Azure AD token from OIDC token\n\n    Args:\n        azure_ad_token: str\n        azure_client_id: Optional[str]\n        azure_tenant_id: Optional[str]\n        scope: str\n\n    Returns:\n        `azure_ad_token_access_token` - str\n    \"\"\"\n    if scope is None:\n        scope = \"https://cognitiveservices.azure.com/.default\"\n    azure_authority_host: Final = os.getenv(\"AZURE_AUTHORITY_HOST\", \"https://login.microsoftonline.com\")\n    azure_client_id = azure_client_id or os.getenv(\"AZURE_CLIENT_ID\")\n    azure_tenant_id = azure_tenant_id or os.getenv(\"AZURE_TENANT_ID\")\n    if azure_client_id is None or azure_tenant_id is None:\n        raise AzureOpenAIError(\n            status_code=422,\n            message=\"AZURE_CLIENT_ID and AZURE_TENANT_ID must be set\",\n        )\n\n    oidc_token: Final = get_secret_str(azure_ad_token)\n\n    if oidc_token is None:\n        raise AzureOpenAIError(\n            status_code=401,\n            message=\"OIDC token could not be retrieved from secret manager.\",\n        )\n\n    azure_ad_token_cache_key: Final = json.dumps(\n        {\n            \"azure_client_id\": azure_client_id,\n            \"azure_tenant_id\": azure_tenant_id,\n            \"azure_authority_host\": azure_authority_host,\n            \"oidc_token\": oidc_token,","sourceCodeStart":177,"sourceCodeEnd":213,"githubUrl":"https://github.com/BerriAI/litellm/blob/6c2dcb801bf2b75c18f1bb24140e7cf57465cc4d/litellm/llms/azure/common_utils.py#L177-L213","documentation":"LiteLLM's Azure AD (OIDC/managed-identity) token flow requires a client ID and tenant ID to build the OAuth 2.0 client-credentials request against Azure's authority host. The code first checks the explicit azure_client_id/azure_tenant_id arguments, then falls back to the AZURE_CLIENT_ID and AZURE_TENANT_ID environment variables. If both lookups fail for either value, it raises AzureOpenAIError 422 because the token request cannot be constructed.","triggerScenarios":"Calling an Azure deployment with azure_ad_token (an OIDC token, e.g. from a cloud workload identity) but without passing azure_client_id/azure_tenant_id and without AZURE_CLIENT_ID and/or AZURE_TENANT_ID set in the environment. The path is hit whenever get_azure_ad_token_from_oidc runs and either env var (and argument) is absent.","commonSituations":"Using Azure AD token auth on Azure Kubernetes Service / GitHub Actions OIDC without exporting the workload identity env vars; rotating secrets and dropping AZURE_TENANT_ID from the deployment manifest; running the proxy in a new container image that does not carry the env vars; typos like AZURE_CLIENTID.","solutions":["Set both env vars: export AZURE_CLIENT_ID=<app/client id> and export AZURE_TENANT_ID=<tenant id> (or add them to your .env / container env).","Or pass the IDs explicitly where LiteLLM accepts azure AD config (e.g. litellm.modify_params or the proxy model config) instead of relying on env vars.","Verify with: python -c \"import os; print(os.getenv('AZURE_CLIENT_ID'), os.getenv('AZURE_TENANT_ID'))\" before starting the proxy/SDK call.","If you did not intend OIDC auth, remove the azure_ad_token input so LiteLLM uses api_key auth instead."],"exampleFix":"# before\nos.environ[\"AZURE_CLIENT_ID\"] = \"\"  # empty string is falsy -> still errors\nresp = litellm.completion(model=\"azure/<dep>\", messages=[...], azure_ad_token=oidc)\n\n# after\nos.environ[\"AZURE_CLIENT_ID\"] = \"11111111-1111-1111-1111-111111111111\"\nos.environ[\"AZURE_TENANT_ID\"] = \"22222222-2222-2222-2222-222222222222\"\nresp = litellm.completion(model=\"azure/<dep>\", messages=[...], azure_ad_token=oidc)","handlingStrategy":"validation","validationCode":"import os\n\ndef validate_azure_oidc_config() -> None:\n    missing = [v for v in (\"AZURE_CLIENT_ID\", \"AZURE_TENANT_ID\") if not os.getenv(v)]\n    if missing:\n        raise ConfigError(f\"Missing required env vars: {missing}\")","typeGuard":null,"tryCatchPattern":"try:\n    resp = litellm.completion(model=\"azure/dep\", messages=msgs, azure_ad_token=oidc)\nexcept AzureOpenAIError as e:\n    if e.status_code == 422 and \"AZURE_CLIENT_ID\" in str(e):\n        raise ConfigError(\"Azure OIDC env vars not set\") from e\n    raise","preventionTips":["Assert AZURE_CLIENT_ID and AZURE_TENANT_ID at process startup, not at call time.","Put Azure env vars in one .env file loaded by a single config module.","Add a startup healthcheck to proxies/containers that fails fast on missing auth config."],"tags":["azure","configuration","environment-variables","authentication","oidc"],"backgroundTag":null,"analyzedSha":"6c2dcb801bf2b75c18f1bb24140e7cf57465cc4d","analyzedAt":"2026-08-15T07:12:03.035Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}