redis/redis-py · error · ValueError
Either maint_notifications_pool_handler or oss_cluster_maint
Error message
Either maint_notifications_pool_handler or oss_cluster_maint_notifications_handler must be set
What it means
Internal guard in _update_maint_notifications_configs_for_connections (free/idle connections branch). It requires that exactly one of maint_notifications_pool_handler or oss_cluster_maint_notifications_handler is set when iterating free connections; if both are None the pool cannot decide how to configure each connection. This indicates the caller passed neither handler, which should not happen via public API.
Source
Thrown at redis/asyncio/connection.py:2199
"""Update the maintenance notifications config for all connections in the pool."""
async with self._get_pool_lock():
for conn in list(self._get_free_connections()):
if oss_cluster_maint_notifications_handler:
conn.set_maint_notifications_cluster_handler_for_connection(
oss_cluster_maint_notifications_handler
)
conn.maint_notifications_config = (
oss_cluster_maint_notifications_handler.config
)
elif maint_notifications_pool_handler:
conn.set_maint_notifications_pool_handler_for_connection(
maint_notifications_pool_handler
)
conn.maint_notifications_config = (
maint_notifications_pool_handler.config
)
else:
raise ValueError(
"Either maint_notifications_pool_handler or "
"oss_cluster_maint_notifications_handler must be set"
)
await conn.disconnect()
for conn in list(self._get_in_use_connections()):
if oss_cluster_maint_notifications_handler:
# Use set_maint_notifications_cluster_handler_for_connection
# (not _configure_maintenance_notifications) so the parser is
# obtained from the connection itself. _configure_* requires a
# parser argument and would raise here; it would also reset the
# connection's orig_* settings, which is wrong for an in-use
# (active) connection. This mirrors the idle-connection branch
# above and the pool-handler branches.
conn.set_maint_notifications_cluster_handler_for_connection(
oss_cluster_maint_notifications_handler
)
conn.maint_notifications_config = (View on GitHub (pinned to da03cdc7e8)
Solutions
- Do not call the private _update_maint_notifications_configs_for_connections directly; use update_maint_notifications_config(config[, oss_cluster_handler]) which always supplies a handler.
- If you must call it, pass exactly one of maint_notifications_pool_handler or oss_cluster_maint_notifications_handler.
- Audit your subclass to ensure it forwards both arguments from the public path.
Example fix
// before
await pool._update_maint_notifications_configs_for_connections(
maint_notifications_pool_handler=None,
oss_cluster_maint_notifications_handler=None,
)
// after
await pool.update_maint_notifications_config(
MaintNotificationsConfig(enabled=True)
) Defensive patterns
Strategy: validation
Validate before calling
def handlers_present(pool_handler, oss_handler) -> bool:
return bool(pool_handler) or bool(oss_handler)
# before calling the private updater:
assert handlers_present(pool_handler, oss_handler) Type guard
def exactly_one_handler_set(pool_handler, oss_handler) -> bool:
return bool(pool_handler) ^ bool(oss_handler) Try / catch
try:
await pool._update_maint_notifications_configs_for_connections(
maint_notifications_pool_handler=h, oss_cluster_maint_notifications_handler=None)
except ValueError as e:
if 'must be set' in str(e):
# route through the public update API instead
... Prevention
- Do not call private _update_*_for_connections directly; use update_maint_notifications_config.
- Always pass exactly one handler when calling internal update helpers.
- Audit subclasses that wrap maintenance updates.
When it happens
Trigger: Calling the private _update_maint_notifications_configs_for_connections() with both handler arguments set to None. Reachable only if a subclass or internal caller bypasses the public update_maint_notifications_config entry point and invokes the per-connection updater directly without a handler.
Common situations: Subclassing the pool and overriding/wrapping the maintenance update helpers incorrectly; library upgrades where an internal signature changed; direct calls into private methods during custom orchestration.
Related errors
- Cannot disable maintenance notifications after enabling them
- Maintenance notifications handlers on connection are only su
- Maintenance notifications are only supported with RESP versi
- To configure maintenance notifications, a parser must be pro
- "max_connections" must be a positive integer
AI-assisted analysis of redis/redis-py@da03cdc7e8 (2026-08-04).
Data as JSON: /data/errors/2a0dadff76f9fa39.json.
Report an issue: GitHub.