redis/redis-py · error · RedisError
Maintenance notifications are only supported with RESP…
Error message
Maintenance notifications are only supported with RESP version 3
What it means
Cluster-mode counterpart of error 40: RedisCluster.__init__ validates maint_notifications_config before constructing NodesManager, and raises RedisError if enabled=True but protocol != 3. Validated early so a bad config does not leak an open NodesManager.
Solutions
- Set protocol=3 on the RedisCluster(...) call that enables maint notifications.
- If RESP2 is mandatory, leave maint_notifications_config=None / enabled=False.
- Confirm the cluster runs Redis >= 7.x with RESP3 push support.
Example fix
// before
client = RedisCluster(
host='localhost', port=7000,
maint_notifications_config=MaintNotificationsConfig(enabled=True),
protocol=2,
)
// after
client = RedisCluster(
host='localhost', port=7000,
maint_notifications_config=MaintNotificationsConfig(enabled=True),
protocol=3,
) Defensive patterns
Strategy: validation
Validate before calling
from redis._parsers.helpers import check_protocol_version
if maint_cfg and maint_cfg.enabled and not check_protocol_version(protocol, 3):
raise ValueError('enable RESP3 (protocol=3) before cluster maint notifications') Type guard
def can_use_cluster_maint_notifications(protocol: int | None) -> bool:
return check_protocol_version(protocol, 3) Try / catch
try:
client = RedisCluster(host=..., port=..., maint_notifications_config=cfg, protocol=protocol)
except RedisError as e:
if 'RESP version 3' in str(e):
client = RedisCluster(host=..., port=..., maint_notifications_config=None, protocol=protocol)
else:
raise Prevention
- Pair maint_notifications_config with protocol=3 in a single config helper.
- Unit-test the pairing for cluster clients.
When it happens
Trigger: RedisCluster(host=..., port=..., maint_notifications_config=MaintNotificationsConfig(enabled=True), protocol=2); or enabling notifications on a cluster client while the deployment default protocol is RESP2.
Common situations: Enabling server-pushed maintenance notifications on a cluster whose other clients still negotiate RESP2; upgrading a cluster deployment and forgetting to bump protocol to 3.
Related errors
- Maintenance notifications are not supported with Unix…
- Maintenance notifications are only supported with RESP…
- Maintenance notifications handlers on connection are only…
- Maintenance notifications handlers on connection are only…
- Maintenance notifications handlers on connection are only…
AI-assisted analysis of redis/redis-py@6a6b581b48 (2026-08-10).
Data as JSON: /api/errors/029ec4de00c7744f.
Report an issue: GitHub.
Appendix: source
Thrown at redis/asyncio/cluster.py:573
# Build the client-level HIMPORT registry once (always empty at construction)
# and share the same object with every node connection. It rides in
# connection_kwargs -> ClusterNode -> each node's Connection, so the registry is
# shared cluster-wide and runtime himport_prepare mutates one object. (Async has
# no per-node Redis client, so the object flows via connection_kwargs directly to
# the Connection, which is internal plumbing, not a public param.)
self._himport_registry = HImportRegistry()
kwargs["himport_registry"] = self._himport_registry
self.connection_kwargs = kwargs
# Validate maint_notifications_config before NodesManager is constructed
# so that a bad config doesn't leak an open NodesManager.
if (
maint_notifications_config
and maint_notifications_config.enabled
and not check_protocol_version(protocol, 3)
):
raise RedisError(
"Maintenance notifications are only supported with RESP version 3"
)
if check_protocol_version(protocol, 3) and maint_notifications_config is None:
maint_notifications_config = MaintNotificationsConfig()
# Initialize to None so aclose() and any error-path code never sees an
# unset slot, even if __init__ raises before the mixin runs.
self._oss_cluster_maint_notifications_handler = None
if startup_nodes:
passed_nodes = []
for node in startup_nodes:
passed_nodes.append(
ClusterNode(node.host, node.port, **self.connection_kwargs)
)
startup_nodes = passed_nodes
else:
startup_nodes = []
if host and port:View on GitHub (pinned to 6a6b581b48)