redis/redis-py · error · DataError

XREAD max_count must be a positive integer

Error message

XREAD max_count must be a positive integer

What it means

Raised by xread() (redis/commands/core.py:7918) as a DataError when max_count is not an int or is < 1. max_count is the cumulative MAXCOUNT cap across all streams (unlike per-stream count) and requires Redis >= 8.10.0. A separate check at line 7919 also enforces max_count >= count when both are set.

Solutions

  1. Pass an int >= 1 for max_count, or None to disable the cumulative cap.
  2. Ensure max_count >= count when both are set (the library enforces this at line 7919).
  3. Verify your Redis server is >= 8.10.0 before using MAXCOUNT/MAXSIZE.

Example fix

# before
client.xread(streams, count=100, max_count=50)
# after
client.xread(streams, count=50, max_count=100)
Defensive patterns

Strategy: validation

Validate before calling

def safe_xread_max_count(count, max_count):
    if max_count is None:
        return None
    if not isinstance(max_count, int) or isinstance(max_count, bool) or max_count < 1:
        raise DataError('XREAD max_count must be a positive int')
    if count is not None and max_count < count:
        raise DataError('XREAD max_count must be >= count')
    return max_count

Type guard

def is_valid_max_count(count, mc) -> bool:
    return isinstance(mc, int) and not isinstance(mc, bool) and mc >= 1 and (count is None or mc >= count)

Try / catch

from redis.exceptions import DataError
try:
    client.xread(streams, count=c, max_count=mc)
except DataError as e:
    if 'max_count' in str(e):
        client.xread(streams, count=c)  # drop the cumulative cap
    else:
        raise

Prevention

When it happens

Trigger: Calling client.xread(streams, max_count=0), max_count=-1, max_count='500', or max_count=100.5. Also raised indirectly if max_count < count. Pass None to disable.

Common situations: Using max_count against an older Redis (< 8.10.0) where the server rejects MAXCOUNT, setting max_count smaller than count (logical contradiction), or env-sourced string values.

Related errors


AI-assisted analysis of redis/redis-py@6a6b581b48 (2026-08-10). Data as JSON: /api/errors/21429cfb89b883f8. Report an issue: GitHub.

Appendix: source

Thrown at redis/commands/core.py:7918

                  may still be returned. Must be a positive integer. Requires
                  Redis >= 8.10.0.

        For more information, see https://redis.io/commands/xread
        """
        pieces = []
        if block is not None:
            if not isinstance(block, int) or block < 0:
                raise DataError("XREAD block must be a non-negative integer")
            pieces.append(b"BLOCK")
            pieces.append(str(block))
        if count is not None:
            if not isinstance(count, int) or count < 1:
                raise DataError("XREAD count must be a positive integer")
            pieces.append(b"COUNT")
            pieces.append(str(count))
        if max_count is not None:
            if not isinstance(max_count, int) or max_count < 1:
                raise DataError("XREAD max_count must be a positive integer")
            if count is not None and max_count < count:
                raise DataError(
                    "XREAD max_count must be greater than or equal to count"
                )
            pieces.append(b"MAXCOUNT")
            pieces.append(str(max_count))
        if max_size is not None:
            if not isinstance(max_size, int) or max_size < 1:
                raise DataError("XREAD max_size must be a positive integer")
            pieces.append(b"MAXSIZE")
            pieces.append(str(max_size))
        if not isinstance(streams, dict) or len(streams) == 0:
            raise DataError("XREAD streams must be a non empty dict")
        pieces.append(b"STREAMS")
        keys, values = zip(*streams.items())
        pieces.extend(keys)
        pieces.extend(values)
        response = self.execute_command("XREAD", *pieces, keys=keys)

View on GitHub (pinned to 6a6b581b48)