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

Raised as a ValueError by _update_maint_notifications_configs_for_connections (connection.py:2683-2686) in the idle/free-connections branch when neither maint_notifications_pool_handler nor oss_cluster_maint_notifications_handler is passed. This is an internal reconfiguration helper invoked after handler setup; both being None means there is no handler to push to connections, which is a programming error in the calling code rather than user config.

Source

Thrown at redis/connection.py:2684

        with self._get_pool_lock():
            for conn in self._get_free_connections():
                if oss_cluster_maint_notifications_handler:
                    # set cluster handler for conn
                    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"
                    )
                conn.disconnect()
            for conn in 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 = (
                        oss_cluster_maint_notifications_handler.config
                    )

View on GitHub (pinned to da03cdc7e8)

Solutions

  1. If you subclass or call _update_maint_notifications_configs_for_connections directly, always pass exactly one of the two handlers (pool handler or OSS cluster handler).
  2. Use the public update_maint_notifications_config() entry point instead of the internal helper — it validates and supplies the handler for you.
  3. Ensure you are on a current redis-py version; if hitting this through normal API calls, report it as a bug after confirming no subclass is involved.

Example fix

# before (internal helper called without a handler)
pool._update_maint_notifications_configs_for_connections(
    maint_notifications_pool_handler=None,
    oss_cluster_maint_notifications_handler=None)

# after (use the public API, which supplies a handler)
pool.update_maint_notifications_config(
    MaintNotificationsConfig(enabled=True))
Defensive patterns

Strategy: validation

Validate before calling

def safe_update_configs(pool, pool_handler=None, oss_handler=None):
    if pool_handler is None and oss_handler is None:
        raise ValueError("Exactly one handler (pool or oss) must be provided")
    pool._update_maint_notifications_configs_for_connections(
        maint_notifications_pool_handler=pool_handler,
        oss_cluster_maint_notifications_handler=oss_handler)

Type guard

def exactly_one_handler(pool_handler, oss_handler) -> bool:
    return (pool_handler is not None) ^ (oss_handler is not None)

Try / catch

try:
    pool._update_maint_notifications_configs_for_connections(
        maint_notifications_pool_handler=h1, oss_cluster_maint_notifications_handler=h2)
except ValueError as e:
    if "must be set" in str(e):
        # fall back to the public API which supplies a handler
        pool.update_maint_notifications_config(MaintNotificationsConfig(enabled=True))
    else:
        raise

Prevention

When it happens

Trigger: Internal/library code (or a subclass override) calling _update_maint_notifications_configs_for_connections with both handler arguments omitted/None. Not reachable through normal public API usage under correct internal flow, because update_maint_notifications_config always supplies one before calling it.

Common situations: Subclassing the connection pool and overriding/wrapping maintenance-notification logic but forgetting to forward a handler; race during reconfiguration where handlers are cleared before the update runs; bugs in custom pool extensions.

Related errors


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