Check for existing issues
Related but different: #37335 / #37341 (async client: username passed alongside credential_provider) and #30633 (adds the credential provider to the sync URL/pool clients). Neither touches init_redis_cluster, which is the path below.
What happened?
With Azure Entra auth enabled on a cluster-mode Redis cache (redis_startup_nodes, Azure Managed Redis with the OSS cluster policy), the proxy cannot start. proxy_server._init_cache builds the sync redis.RedisCluster first, and _redis.py::init_redis_cluster has no Entra path — it never attaches the AzureADCredentialProvider that the async cluster path (get_redis_async_client) uses. The sync client sends AUTH with no token, Redis answers invalid username-password pair, and startup exits.
So azure_redis_ad_token works for the standard sync/async clients and for the async cluster client, but a cluster-mode cache can never boot with it.
User Flow
Before: an operator running Azure Managed Redis (OSS cluster policy) with a managed identity enables azure_redis_ad_token.
- The operator sets
cache_params.azure_redis_ad_token: true + azure_client_id, and REDIS_USERNAME = the identity's object id.
- The proxy starts, reaches
_init_cache, and constructs Cache(**cache_params) → RedisClusterCache → get_redis_client → init_redis_cluster.
redis.RedisCluster(...) raises RedisClusterException: ... invalid username-password pair.
- The container exits with
Application startup failed. Exiting. and crashloops. The operator has to revert to password.
After: the same config boots; init_redis_cluster passes a credential_provider (sync AzureADCredentialProvider, mirroring the async cluster branch) instead of username/password, and /cache/ping returns healthy.
Proof the bug occurs
Config (proxy config.yaml):
litellm_settings:
cache: true
cache_params:
type: redis
redis_startup_nodes: os.environ/REDIS_CLUSTER_NODES # host:10000 of an Azure Managed Redis, OSS cluster policy
azure_redis_ad_token: true
azure_client_id: os.environ/AZURE_CLIENT_ID # user-assigned managed identity
namespace: os.environ/REDIS_NAMESPACE
ssl: true
ssl_check_hostname: false
Env: AZURE_CLIENT_ID=<uami client id>, REDIS_USERNAME=<uami object id>, no REDIS_PASSWORD. The identity is bound to the database's default access policy (verified separately: the same identity authenticates with a token using redis-cli/the async path).
Startup log (litellm v1.97.0, ghcr.io/berriai/litellm:1.97.0, Azure Container Apps):
File ".../litellm/proxy/proxy_server.py", line 4242, in _init_cache
litellm.cache = Cache(**cache_params)
File ".../litellm/caching/caching.py", line 191, in __init__
self.cache: BaseCache = RedisClusterCache(**cluster_kwargs)
File ".../litellm/caching/redis_cluster_cache.py", line 28, in __init__
super().__init__(*args, **kwargs)
File ".../litellm/caching/redis_cache.py", line 306, in __init__
self.redis_client = get_redis_client(**redis_kwargs)
File ".../litellm/_redis.py", line 573, in get_redis_client
return init_redis_cluster(redis_kwargs)
File ".../litellm/_redis.py", line 506, in init_redis_cluster
return redis.RedisCluster(startup_nodes=new_startup_nodes, **cluster_kwargs)
File ".../redis/cluster.py", line 1738, in initialize
raise RedisClusterException(
redis.exceptions.RedisClusterException: Redis Cluster cannot be connected. Please provide at least one reachable node: invalid username-password pair
Application startup failed. Exiting.
Reverting cache_params to password: os.environ/REDIS_PASSWORD (same nodes, same image) boots and /cache/ping is healthy — so the nodes, TLS and cluster settings are fine; only the auth path differs.
Suggested fix: in init_redis_cluster, detect the Azure (and GCP) connect-func marker the same way get_redis_async_client does for the async cluster, build a sync CredentialProvider, and drop username/password from cluster_kwargs (so it also avoids the #37335 conflict).
What part of LiteLLM is this about?
LiteLLM Proxy Server (caching / Redis)
What LiteLLM version are you on ?
v1.97.0
Twitter / LinkedIn details
No response
Check for existing issues
Related but different: #37335 / #37341 (async client:
usernamepassed alongsidecredential_provider) and #30633 (adds the credential provider to the sync URL/pool clients). Neither touchesinit_redis_cluster, which is the path below.What happened?
With Azure Entra auth enabled on a cluster-mode Redis cache (
redis_startup_nodes, Azure Managed Redis with the OSS cluster policy), the proxy cannot start.proxy_server._init_cachebuilds the syncredis.RedisClusterfirst, and_redis.py::init_redis_clusterhas no Entra path — it never attaches theAzureADCredentialProviderthat the async cluster path (get_redis_async_client) uses. The sync client sendsAUTHwith no token, Redis answersinvalid username-password pair, and startup exits.So
azure_redis_ad_tokenworks for the standard sync/async clients and for the async cluster client, but a cluster-mode cache can never boot with it.User Flow
Before: an operator running Azure Managed Redis (OSS cluster policy) with a managed identity enables
azure_redis_ad_token.cache_params.azure_redis_ad_token: true+azure_client_id, andREDIS_USERNAME= the identity's object id._init_cache, and constructsCache(**cache_params)→RedisClusterCache→get_redis_client→init_redis_cluster.redis.RedisCluster(...)raisesRedisClusterException: ... invalid username-password pair.Application startup failed. Exiting.and crashloops. The operator has to revert topassword.After: the same config boots;
init_redis_clusterpasses acredential_provider(syncAzureADCredentialProvider, mirroring the async cluster branch) instead of username/password, and/cache/pingreturns healthy.Proof the bug occurs
Config (proxy
config.yaml):Env:
AZURE_CLIENT_ID=<uami client id>,REDIS_USERNAME=<uami object id>, noREDIS_PASSWORD. The identity is bound to the database'sdefaultaccess policy (verified separately: the same identity authenticates with a token usingredis-cli/the async path).Startup log (litellm
v1.97.0,ghcr.io/berriai/litellm:1.97.0, Azure Container Apps):Reverting
cache_paramstopassword: os.environ/REDIS_PASSWORD(same nodes, same image) boots and/cache/pingis healthy — so the nodes, TLS and cluster settings are fine; only the auth path differs.Suggested fix: in
init_redis_cluster, detect the Azure (and GCP) connect-func marker the same wayget_redis_async_clientdoes for the async cluster, build a syncCredentialProvider, and dropusername/passwordfromcluster_kwargs(so it also avoids the #37335 conflict).What part of LiteLLM is this about?
LiteLLM Proxy Server (caching / Redis)
What LiteLLM version are you on ?
v1.97.0
Twitter / LinkedIn details
No response