redis/redis-py · warning · ValueError
Evictions count is above cache size
Error message
Evictions count is above cache size
What it means
Raised as ValueError in LRUPolicy.evict_many when the requested count exceeds the number of entries currently in the cache collection. evict_many pops count items via popitem; asking for more than exist would underflow the ordered dict, so it validates up front.
Solutions
- Clamp the count to the current cache size before calling evict_many: count = min(count, cache.size).
- Use evict_next() in a loop if you need best-effort eviction up to a limit.
- Re-check cache.size immediately before eviction to avoid stale counts.
Example fix
# before keys = policy.evict_many(requested_count) # may exceed size # after keys = policy.evict_many(min(requested_count, cache.size))
Defensive patterns
Strategy: validation
Validate before calling
count = min(count, cache.size) keys = policy.evict_many(count)
Try / catch
try:
keys = policy.evict_many(count)
except ValueError as e:
if "above cache size" in str(e):
keys = policy.evict_many(cache.size)
else:
raise Prevention
- Always clamp eviction counts to the live cache size.
- Re-read size immediately before batch eviction.
When it happens
Trigger: Calling eviction_policy.evict_many(n) with n greater than len(cache.collection). This is an internal client-side-caching (CSC) path; evict_many is invoked by cache management code when evicting batches.
Common situations: A bug in cache management computing an eviction count from a stale size. Calling evict_many right after a flush or on a nearly-empty cache. Misuse of the eviction policy API directly with an oversized count.
Related errors
- Given entry does not belong to the cache
- Eviction policy should be associated with valid cache.
- Cache must implement CacheInterface
- Cannot create cache key.
- Prefix can only be used with bcast
AI-assisted analysis of redis/redis-py@6a6b581b48 (2026-08-10).
Data as JSON: /api/errors/2a46dae3b213076c.
Report an issue: GitHub.
Appendix: source
Thrown at redis/cache.py:329
return self._cache
@cache.setter
def cache(self, cache: CacheInterface):
self._cache = cache
@property
def type(self) -> EvictionPolicyType:
return EvictionPolicyType.time_based
def evict_next(self) -> CacheKey:
self._assert_cache()
popped_entry = self._cache.collection.popitem(last=False)
return popped_entry[0]
def evict_many(self, count: int) -> List[CacheKey]:
self._assert_cache()
if count > len(self._cache.collection):
raise ValueError("Evictions count is above cache size")
popped_keys = []
for _ in range(count):
popped_entry = self._cache.collection.popitem(last=False)
popped_keys.append(popped_entry[0])
return popped_keys
def touch(self, cache_key: CacheKey) -> None:
self._assert_cache()
if self._cache.collection.get(cache_key) is None:
raise ValueError("Given entry does not belong to the cache")
self._cache.collection.move_to_end(cache_key)
def _assert_cache(self):View on GitHub (pinned to 6a6b581b48)