{"record":{"id":"eb52557f006d94b2","repo":"BerriAI/litellm","slug":"gcp-iam-authentication-failed","errorCode":null,"errorMessage":"GCP IAM authentication failed","messagePattern":"GCP IAM authentication failed","errorType":"exception","errorClass":"AuthenticationError","httpStatus":null,"severity":"error","filePath":"litellm/_redis.py","lineNumber":209,"sourceCode":"        from redis.utils import str_if_bytes\n\n        self._parser.on_connect(self)\n\n        auth_args: Final = (_generate_gcp_iam_access_token(service_account),)\n        self.send_command(\"AUTH\", *auth_args, check_health=False)\n\n        try:\n            auth_response = self.read_response()\n        except AuthenticationWrongNumberOfArgsError:\n            # Fallback to password auth if IAM fails\n            if hasattr(self, \"password\") and self.password:\n                self.send_command(\"AUTH\", self.password, check_health=False)\n                auth_response = self.read_response()\n            else:\n                raise\n\n        if str_if_bytes(auth_response) != \"OK\":\n            raise AuthenticationError(\"GCP IAM authentication failed\")\n\n    return iam_connect\n\n\ndef _build_azure_credential(\n    azure_client_id: str | None = None,\n    azure_tenant_id: str | None = None,\n    azure_client_secret: str | None = None,\n):\n    \"\"\"\n    Build a long-lived Azure credential object.\n\n    Azure SDK credentials cache tokens internally and handle expiry/refresh\n    transparently, so this should be called once and the result reused.\n    \"\"\"\n    try:\n        from azure.identity import (\n            ClientSecretCredential,","sourceCodeStart":191,"sourceCodeEnd":227,"githubUrl":"https://github.com/BerriAI/litellm/blob/77b7c6c40c0c5aa5fbcb1d6a1825ac39ca8829b8/litellm/_redis.py#L191-L227","documentation":"litellm's Redis layer supports GCP Memorystore IAM auth: the connection function sends an AUTH command with an IAM-derived token and expects the server to answer 'OK'. If the response is anything else, redis.AuthenticationError('GCP IAM authentication failed') is raised — the token was accepted syntactically but the server rejected it (or the handshake produced a non-OK reply).","triggerScenarios":"Connecting to Memorystore for Redis with IAM auth enabled where the workload's service account lacks the Redis IAM role (e.g. roles/redis.instanceUser / redis Enterprise Admin), or gcp_service_account credentials are wrong/expired; also when the fallback to password auth is unavailable (no password set) and IAM failed.","commonSituations":"Running the proxy on GKE/Cloud Run/Compute with Application Default Credentials of a SA missing Redis permissions; locally with a user creds that is not authorized on the instance; IAM enabled on the instance but connecting with a token for a different identity; clock skew breaking signed tokens.","solutions":["Grant the connecting identity the Redis IAM auth role: gcloud projects add-iam-policy-binding ... --role=roles/redis.instanceUser --member=...","Verify the identity in use: gcloud auth application-default print-identity-token / check the SA attached to your workload","Confirm Memorystore instance has IAM auth enabled and you connect over TLS on port 6379 from an authorized network","Provide a valid gcp_service_account (path/JSON) in the Redis cache config, or fall back to ACL/password auth by supplying a password"],"exampleFix":"# before\nRedisCache(host=\"10.x.x.x\", port=6379, gcp_service_account=\"/secrets/sa.json\")\n# SA lacks IAM role -> AuthenticationError: GCP IAM authentication failed\n\n# after\ngcloud projects add-iam-policy-binding my-proj \\\n  --member=\"serviceAccount:proxy@my-proj.iam.gserviceaccount.com\" \\\n  --role=\"roles/redis.instanceUser\"\n# then retry connection","handlingStrategy":"try-catch","validationCode":"import redis\n\ndef can_auth_memorystore(host: str, port: int = 6379) -> bool:\n    \"\"\"Cheap pre-flight: server reachable + RESP AUTH path alive.\"\"\"\n    try:\n        with redis.Redis(host=host, port=port, ssl=True, socket_connect_timeout=5):\n            return True\n    except (redis.ConnectionError, redis.AuthenticationError):\n        return False","typeGuard":null,"tryCatchPattern":"from redis.exceptions import AuthenticationError\n\ntry:\n    cache = RedisCache(host=..., port=6379, gcp_service_account=\"/secrets/sa.json\")\n    cache.ping()\nexcept AuthenticationError as e:\n    if \"GCP IAM\" in str(e):\n        raise RuntimeError(\n            \"Memorystore IAM rejected credentials: grant roles/redis.instanceUser \"\n            \"to the connecting service account\"\n        ) from e\n    raise","preventionTips":["Run `gcloud projects get-iam-policy` pre-deploy to assert the workload SA has roles/redis.instanceUser","Add a startup Redis ping to the proxy health check so auth failures surface at boot, not mid-request","Keep the SA key file readable only by the proxy process and rotate it; test with ADC in dev first"],"tags":["redis","gcp","iam","authentication","memorystore","cache"],"backgroundTag":"authentication-failed","analyzedSha":"77b7c6c40c0c5aa5fbcb1d6a1825ac39ca8829b8","analyzedAt":"2026-08-18T11:44:31.656Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}