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 ValueError by ConnectionPool.__init__ when max_connections is not an int or is negative. Note the line `max_connections = max_connections or 100` first substitutes 100 for falsy values (None, 0, ''), so a 0 becomes 100 and will not raise; only a genuinely negative integer or a non-int (float, str) trips the check. The cap keeps the bounded pool from over-allocating.
Solutions
- Pass a positive int: max_connections=100. To get the default, omit the argument or pass None.
- Coerce config-sourced values: max_connections=int(value) and assert it is >= 0.
- Remember 0 means 'use default (100)', not 'unlimited' — redis-py has no unlimited option.
Example fix
# before pool = ConnectionPool(max_connections=os.environ['MAX_CONN']) # str -> raises # after pool = ConnectionPool(max_connections=int(os.environ['MAX_CONN']))
Defensive patterns
Strategy: validation
Validate before calling
def coerce_max_connections(value):
value = int(value) # raise early on non-numeric strings
if value < 0:
raise ValueError('max_connections must be >= 0')
return value or 100 # 0 -> default
pool = ConnectionPool(max_connections=coerce_max_connections(cfg.get('max_connections'))) Type guard
def is_valid_max_connections(value) -> bool:
return isinstance(value, int) and not isinstance(value, bool) and value >= 0 Try / catch
try:
pool = ConnectionPool(max_connections=raw)
except ValueError:
pool = ConnectionPool(max_connections=int(raw)) Prevention
- Always coerce config/env values to int before passing as max_connections.
- Remember 0 means default (100), not unlimited.
- Reject negative values in config validation.
When it happens
Trigger: Passing max_connections=-1, max_connections=1.5, or max_connections='10' (string) to ConnectionPool. Pulling max_connections from config without coercing to int.
Common situations: Config value loaded as a string (e.g. os.environ returns str) and passed straight through. Negative values used to mean 'unlimited' by mistake. Float arithmetic producing 99.0.
Related errors
- Cache must implement CacheInterface
- Error setting client name
- Invalid Database
- Invalid SSL Certificate Requirements Flag
- Invalid ssl verify flag
AI-assisted analysis of redis/redis-py@6a6b581b48 (2026-08-10).
Data as JSON: /api/errors/9a755d5ab412d55e.
Report an issue: GitHub.
Appendix: source
Thrown at redis/connection.py:2993
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 6a6b581b48)