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 by LRUPolicy.evict_many (redis/cache.py:329) when the requested count exceeds the number of entries currently in the cache collection. The LRU policy cannot evict more items than exist; this is a caller invariant violation rather than a cache miss.

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 da03cdc7e8)

Solutions

  1. Cap the requested count at len(cache.collection) before calling evict_many.
  2. Call evict_next() in a loop bounded by min(count, size) instead.
  3. Re-check the collection size immediately before eviction to avoid races.

Example fix

# before
keys = policy.evict_many(requested_count)  # ValueError if requested_count > size
# after
size = len(cache.collection)
keys = policy.evict_many(min(requested_count, size))
Defensive patterns

Strategy: validation

Validate before calling

n = min(requested_count, len(cache.collection))
if n > 0:
    policy.evict_many(n)

Type guard

def eviction_count_ok(policy, n) -> bool:
    return 0 <= n <= len(policy.cache.collection)

Try / catch

try:
    policy.evict_many(n)
except ValueError:
    policy.evict_many(len(cache.collection))

Prevention

When it happens

Trigger: Calling evict_many(n) with n greater than the live entry count; computing an eviction count from an external metric (e.g. evictions counter) that overshoots the actual collection size.

Common situations: Bug in a custom eviction trigger; off-by-one when evicting a batch; race where entries were removed between sizing and evicting.

Related errors


AI-assisted analysis of redis/redis-py@da03cdc7e8 (2026-08-04). Data as JSON: /data/errors/2a46dae3b213076c.json. Report an issue: GitHub.