redis/redis-py · error · NotImplementedError
get_credentials must be implemented
Error message
get_credentials must be implemented
What it means
The base class redis.credentials.CredentialProvider leaves get_credentials() unimplemented (redis/credentials.py:14) and raises NotImplementedError to force subclasses to supply credentials. redis-py calls get_credentials() (or the async get_credentials_async()) during the AUTH/HELLO handshake to obtain the (password,) or (username, password) tuple. If you registered a custom credential provider that does not override this method, every connect attempt fails at authentication.
Solutions
- Override get_credentials(self) in your CredentialProvider subclass to return a (password,) or (username, password) tuple.
- If your provider is async-only, also override get_credentials_async so it does not fall back to the unimplemented sync stub.
- Prefer reusing UsernamePasswordCredentialProvider for static credentials rather than subclassing the base yourself.
- Unit-test the provider in isolation (assert it returns a tuple of the right arity) before wiring it into the client.
Example fix
// before
class MyProvider(redis.credentials.CredentialProvider):
pass
client = redis.Redis(credential_provider=MyProvider())
// after
class MyProvider(redis.credentials.CredentialProvider):
def get_credentials(self):
tok = fetch_token() # your rotation logic
return (USER, tok)
async def get_credentials_async(self):
tok = await fetch_token_async()
return (USER, tok) Defensive patterns
Strategy: validation
Validate before calling
from redis.credentials import CredentialProvider
def is_provider_complete(p: CredentialProvider) -> bool:
return type(p).get_credentials is not CredentialProvider.get_credentials
assert is_provider_complete(MyProvider()), 'get_credentials must be implemented' Type guard
from redis.credentials import CredentialProvider, UsernamePasswordCredentialProvider
def valid_provider(p) -> bool:
return isinstance(p, CredentialProvider) and \
type(p).get_credentials is not CredentialProvider.get_credentials Prevention
- Prefer UsernamePasswordCredentialProvider for static credentials instead of subclassing the base.
- Add a unit test asserting your provider returns a 1- or 2-tuple before wiring it into the client.
- Override both get_credentials and get_credentials_async for async-only providers.
When it happens
Trigger: Instantiating Redis(..., credential_provider=MyProvider()) where MyProvider subclasses CredentialProvider but does not implement get_credentials(); or passing a provider whose get_credentials was renamed/typo'd. The error surfaces on the first command that triggers a connection (connect()/get_connection) because that is when the credentials are read for AUTH.
Common situations: Writing a provider for IAM/EntraID/secret-manager rotation that forgets to implement the synchronous hook; porting from UsernamePasswordCredentialProvider and overriding only __init__; a refactor that renames the method; async-only code paths where the default get_credentials_async falls back to the unimplemented sync method.
Related errors
- Invalid Username or Password
- 'username' and 'password' cannot be passed along with…
- COMMAND DOCS is intentionally not implemented in the client.
- COMMAND INFO is intentionally not implemented in the client.
- DEBUG SEGFAULT is intentionally not implemented in the…
AI-assisted analysis of redis/redis-py@6a6b581b48 (2026-08-10).
Data as JSON: /api/errors/10710e9bf4a171ad.
Report an issue: GitHub.
Appendix: source
Thrown at redis/credentials.py:14
import logging
from abc import ABC, abstractmethod
from typing import Any, Callable, Optional, Tuple, Union
logger = logging.getLogger(__name__)
class CredentialProvider:
"""
Credentials Provider.
"""
def get_credentials(self) -> Union[Tuple[str], Tuple[str, str]]:
raise NotImplementedError("get_credentials must be implemented")
async def get_credentials_async(self) -> Union[Tuple[str], Tuple[str, str]]:
logger.warning(
"This method is added for backward compatibility. "
"Please override it in your implementation."
)
return self.get_credentials()
class StreamingCredentialProvider(CredentialProvider, ABC):
"""
Credential provider that streams credentials in the background.
"""
@abstractmethod
def on_next(self, callback: Callable[[Any], None]):
"""
Specifies the callback that should be invokedView on GitHub (pinned to 6a6b581b48)