Skip to content

[Bug]: Azure Entra Redis auth (azure_redis_ad_token) cannot start the proxy in cluster mode — init_redis_cluster has no credential provider path #37726

Description

@mihidumh

Check for existing issues

  • I have searched the existing issues and checked that my issue is not a duplicate.

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.

  1. The operator sets cache_params.azure_redis_ad_token: true + azure_client_id, and REDIS_USERNAME = the identity's object id.
  2. The proxy starts, reaches _init_cache, and constructs Cache(**cache_params)RedisClusterCacheget_redis_clientinit_redis_cluster.
  3. redis.RedisCluster(...) raises RedisClusterException: ... invalid username-password pair.
  4. 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

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions