redis/redis-py · error · ValueError

"max_connections" must be a positive integer

Error message

"max_connections" must be a positive integer

What it means

Raised as a ValueError by ConnectionPool.__init__ (connection.py:2976-2978) when max_connections is not an int or is negative. Note line 2976 first applies `max_connections = max_connections or 100`, so falsy values (None, 0) are replaced by 100 and pass; only truthy non-int values (e.g. 5.5, "10") or negative ints actually raise.

Source

Thrown at redis/connection.py:2978

        url_options = parse_url(url)

        if "connection_class" in kwargs:
            url_options["connection_class"] = kwargs["connection_class"]

        kwargs.update(url_options)
        return cls(**kwargs)

    def __init__(
        self,
        connection_class=Connection,
        max_connections: Optional[int] = None,
        cache_factory: Optional[CacheFactoryInterface] = None,
        maint_notifications_config: Optional[MaintNotificationsConfig] = None,
        **connection_kwargs,
    ):
        max_connections = max_connections or 100
        if not isinstance(max_connections, int) or max_connections < 0:
            raise ValueError('"max_connections" must be a positive integer')

        self.connection_class = connection_class
        self._connection_kwargs = connection_kwargs
        self.max_connections = max_connections
        self.cache = None
        self._cache_factory = cache_factory

        try:
            supports_maint_notifications = issubclass(
                connection_class, MaintNotificationsAbstractConnection
            )
            is_unix_domain_socket_connection = issubclass(
                connection_class, UnixDomainSocketConnection
            )
        except TypeError:
            supports_maint_notifications = False
            is_unix_domain_socket_connection = False

View on GitHub (pinned to da03cdc7e8)

Solutions

  1. Pass a positive int (or None to use the default of 100): max_connections=50.
  2. If the value comes from config/env, coerce explicitly: max_connections=int(value) after validating it is >= 0.
  3. Do not use a negative number to mean unlimited — there is no unlimited sentinel; choose a large positive int instead.

Example fix

# before
pool = redis.ConnectionPool(max_connections="50")
# or
pool = redis.ConnectionPool(max_connections=50.0)

# after
pool = redis.ConnectionPool(max_connections=int(50))
# or rely on default
pool = redis.ConnectionPool()  # max_connections=100
Defensive patterns

Strategy: validation

Validate before calling

def coerce_max_connections(v):
    if v is None:
        return 100
    v = int(v)
    if v < 0:
        raise ValueError("max_connections must be >= 0")
    return v

pool = redis.ConnectionPool(max_connections=coerce_max_connections(raw))

Type guard

def is_valid_max_connections(v) -> bool:
    return isinstance(v, int) and v >= 0

Try / catch

try:
    pool = redis.ConnectionPool(max_connections=raw)
except ValueError as e:
    if "max_connections" in str(e):
        pool = redis.ConnectionPool(max_connections=int(raw))
    else:
        raise

Prevention

When it happens

Trigger: Passing max_connections as a float (50.0 is still an int check failure? no — 50.0 is a float, isinstance(50.0, int) is False, so it raises), a string ("50"), or a negative integer (-1) to ConnectionPool / BlockingConnectionPool / Redis(max_connections=...). Also via from_url query (?max_connections=-5).

Common situations: Config loaders returning typed values from YAML/JSON that deserialize numbers as floats; env-var parsing that leaves the value as a string; accidentally computing max_connections from an expression that yields a float; passing a negative to mean 'unlimited'.

Related errors


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