redis/redis-py · error · ValueError
Cache must implement CacheInterface
Error message
Cache must implement CacheInterface
What it means
Raised as ValueError by ConnectionPool.__init__ when the cache argument is provided but is not an instance of CacheInterface. redis-py requires a concrete cache object that implements the CacheInterface contract (get/set/delete/flush/etc.) so the invalidation machinery can drive it. Passing a dict, a plain LRUCache from another library, or a half-implemented stub fails this check.
Solutions
- Pass an object that implements CacheInterface, or use cache_config to have redis-py build a default cache for you.
- If you have a custom cache, make the class inherit CacheInterface and implement its abstract methods.
- Drop the cache argument and rely on cache_config when you do not need a custom cache implementation.
Example fix
# before
pool = ConnectionPool(protocol=3, cache={'k': 'v'})
# after
pool = ConnectionPool(protocol=3, cache_config={}) # builds a CacheInterface impl Defensive patterns
Strategy: type-guard
Validate before calling
from redis.cache import CacheInterface
def ensure_cache(cache):
if cache is None or isinstance(cache, CacheInterface):
return cache
raise TypeError('cache must implement CacheInterface; pass cache_config to build a default cache')
pool = ConnectionPool(protocol=3, cache=ensure_cache(user_cache)) Type guard
from redis.cache import CacheInterface
def is_valid_cache(cache) -> bool:
return cache is None or isinstance(cache, CacheInterface) Try / catch
try:
pool = ConnectionPool(protocol=3, cache=user_cache)
except ValueError as e:
if 'Cache must implement CacheInterface' in str(e):
pool = ConnectionPool(protocol=3, cache_config={}) # build a default cache
else:
raise Prevention
- Use cache_config when you don't need a custom cache implementation.
- Make custom caches inherit CacheInterface and implement all abstract methods.
- Never pass a plain dict or third-party cache object as cache.
When it happens
Trigger: Passing cache={'k': 'v'} or cache=cachetools.LRUCache(...) to ConnectionPool. Providing a custom cache object that does not inherit/implement CacheInterface.
Common situations: Assuming any dict-like object works as a cache. Using cache_config (which builds a default cache) vs cache (which must be a CacheInterface) interchangeably. Subclassing without implementing all abstract methods.
Related errors
- Cannot create cache key.
- Cannot retrieve information about server version
- Client caching is only supported with RESP version 3
- Client caching is only supported with RESP version 3
- Error setting client name
AI-assisted analysis of redis/redis-py@6a6b581b48 (2026-08-10).
Data as JSON: /api/errors/322e5e669226b41e.
Report an issue: GitHub.
Appendix: source
Thrown at redis/connection.py:3035
raise RedisError(
"Maintenance notifications are not supported with "
f"{connection_class}"
)
maint_notifications_config = MaintNotificationsConfig(enabled=False)
self._event_dispatcher = self._connection_kwargs.get("event_dispatcher", None)
if self._event_dispatcher is None:
self._event_dispatcher = EventDispatcher()
if connection_kwargs.get("cache_config") or connection_kwargs.get("cache"):
if not check_protocol_version(self._connection_kwargs.get("protocol"), 3):
raise RedisError("Client caching is only supported with RESP version 3")
cache = self._connection_kwargs.get("cache")
if cache is not None:
if not isinstance(cache, CacheInterface):
raise ValueError("Cache must implement CacheInterface")
self.cache = cache
else:
if self._cache_factory is not None:
self.cache = CacheProxy(self._cache_factory.get_cache())
else:
self.cache = CacheFactory(
self._connection_kwargs.get("cache_config")
).get_cache()
init_csc_items()
register_csc_items_callback(
callback=lambda: self.cache.size,
pool_name=get_pool_name(self),
)
connection_kwargs.pop("cache", None)
connection_kwargs.pop("cache_config", None)View on GitHub (pinned to 6a6b581b48)