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 by ConnectionPool.__init__ when max_connections is not an int or is negative. Note the guard checks isinstance int and < 0 (0 is allowed because the line above coerces falsy values to 100). A non-integer (e.g., a string from a URL/env var) or a negative number fails the check. The default when None/0/falsy is 100.
Source
Thrown at redis/asyncio/connection.py:2627
``ValueError`` to be raised. Once parsed, the querystring arguments
and keyword arguments are passed to the ``ConnectionPool``'s
class initializer. In the case of conflicting arguments, querystring
arguments always win.
"""
url_options = parse_url(url)
kwargs.update(url_options)
return cls(**kwargs)
def __init__(
self,
connection_class: Type[AbstractConnection] = Connection,
max_connections: Optional[int] = None,
maint_notifications_config: MaintNotificationsConfig | None = 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
# Resolve the HIMPORT registry. A pre-built ``himport_registry`` (shared, e.g.
# from the cluster client) takes precedence; otherwise build a fresh empty one.
# A registry always exists so runtime ``himport_prepare`` mutates a single object
# every connection already shares. The object stays in ``connection_kwargs`` so
# it reaches every connection. It is injected unconditionally (like other
# auto-added pool kwargs), so a custom ``connection_class`` must accept
# ``**kwargs`` (or a ``himport_registry`` parameter), as built-ins do.
himport_registry = connection_kwargs.get("himport_registry")
if himport_registry is None:
himport_registry = HImportRegistry()
connection_kwargs["himport_registry"] = himport_registry
self.himport_registry = himport_registry
View on GitHub (pinned to da03cdc7e8)
Solutions
- Coerce max_connections to int explicitly before passing it: int(os.environ['MAX_CONN']).
- Ensure the value is a positive integer (>= 0; 0/None becomes the default 100).
- Validate the value at the boundary where you read configuration, not at pool construction.
Example fix
// before pool = ConnectionPool(max_connections=os.environ['REDIS_MAX_CONN']) // after pool = ConnectionPool(max_connections=int(os.environ['REDIS_MAX_CONN']))
Defensive patterns
Strategy: type-guard
Validate before calling
def coerce_max_connections(v):
v = int(v)
if v < 0:
raise ValueError('max_connections must be >= 0')
return v or 100
pool = ConnectionPool(max_connections=coerce_max_connections(os.environ.get('REDIS_MAX_CONN', 100))) Type guard
def is_valid_max_connections(v) -> bool:
return isinstance(v, int) and not isinstance(v, bool) and v >= 0 Try / catch
try:
pool = ConnectionPool(max_connections=raw)
except ValueError as e:
if 'max_connections' in str(e):
raw = int(raw); pool = ConnectionPool(max_connections=raw)\n else:\n raise Prevention
- Coerce config-sourced max_connections to int at the config boundary.
- Reject bool (isinstance(True, int) is True) explicitly if relevant.
- Validate >= 0 before construction.
When it happens
Trigger: Passing max_connections as a non-int (string '50', float 50.0, or None-coerced-but-still-wrong value) or a negative int to ConnectionPool, Redis(connection_pool=...) or via a URL with max_connections in the query string that parses to a string. The check at connection.py:2626 runs before the pool is usable.
Common situations: Reading max_connections from an environment variable or config file as a string and passing it unconverted; passing a float; off-by-one or sign errors computing pool size; URL parsing where the value is a str until coerced elsewhere.
Related errors
- Cannot disable maintenance notifications after enabling them
- Maintenance notifications handlers on connection are only su
- Argument 'db' must be 0 or None in cluster mode
- Unix domain socket is not supported in cluster mode
- RedisCluster requires at least one node to discover the clus
AI-assisted analysis of redis/redis-py@da03cdc7e8 (2026-08-04).
Data as JSON: /data/errors/866cff0b279d0bd1.json.
Report an issue: GitHub.