redis/redis-py · error · ValueError

Cannot enable maintenance notifications for connection…

Error message

Cannot enable maintenance notifications for connection object that doesn't have a host attribute.

What it means

Raised inside _enable_maintenance_notifications when the connection object has no host attribute (getattr(self,'host',None) returns None). Maintenance notifications are keyed to a network host (they communicate a 'moving-endpoint-type' to the server), so a connection without a host — most commonly a UnixDomainSocketConnection or a mock/test double — cannot participate. The library refuses to send the CLIENT MAINT_NOTIFICATIONS command rather than send a malformed one.

Solutions

  1. Do not enable maint_notifications_config on UnixDomainSocketConnection or any host-less connection — disable it (enabled=False) or leave the config unset.
  2. If you wrote a custom Connection subclass, ensure it sets self.host (and exposes the host property) before on_connect runs.
  3. Use a TCP Connection (redis.Connection / Redis(host=...)) when you need maintenance notifications.
  4. Set maint_notifications_config.enabled='auto' only after confirming the transport is TCP.

Example fix

# before
r = redis.Redis(
    unix_socket_path='/tmp/redis.sock',
    protocol=3,
    maint_notifications_config=MaintNotificationsConfig(enabled=True, ...),
)
# after
r = redis.Redis(unix_socket_path='/tmp/redis.sock', protocol=3)  # no maint notifications
Defensive patterns

Strategy: validation

Validate before calling

# before constructing the client
proto = 3
want_maint = bool(maint_cfg and getattr(maint_cfg, 'enabled', False) in (True, 'auto'))
is_tcp = transport in (None, 'tcp')
if want_maint and not is_tcp:
    raise ValueError('maintenance notifications require a TCP (host-based) connection')
r = redis.Redis(host=h, port=p, protocol=proto,
                maint_notifications_config=maint_cfg if (want_maint and is_tcp) else None)

Type guard

def supports_maint_notifications(conn) -> bool:
    return getattr(conn, 'host', None) is not None and isinstance(
        conn, MaintNotificationsAbstractConnection
    )

Try / catch

try:
    r = redis.Redis(unix_socket_path=p, protocol=3, maint_notifications_config=cfg)
    r.ping()
except ValueError as e:
    if 'host attribute' in str(e):
        # disable maint notifications and retry over UDS
        r = redis.Redis(unix_socket_path=p, protocol=3)
    else:
        raise

Prevention

When it happens

Trigger: Constructing a connection whose class does not set self.host (e.g. redis.UnixDomainSocketConnection which uses 'path' instead) with maint_notifications_config enabled=True/='auto', and that config also having a connection handler attached, then triggering on_connect/connect. The guard at connection.py:637-639 fires because host is None.

Common situations: Pointing a maintenance-notifications-enabled client at a local UDS path for testing; reusing a maintenance-notifications config object on a connection class it was not designed for; building a custom Connection subclass that forgets to expose host.

Related errors


AI-assisted analysis of redis/redis-py@6a6b581b48 (2026-08-10). Data as JSON: /api/errors/a27997c54ab275b7. Report an issue: GitHub.

Appendix: source

Thrown at redis/connection.py:639

        if (
            check_protocol_version(self.get_protocol(), 3)
            and self.maint_notifications_config
            and self.maint_notifications_config.enabled
            and self._maint_notifications_connection_handler
            and host is not None
        ):
            self._enable_maintenance_notifications(
                maint_notifications_config=self.maint_notifications_config,
                check_health=check_health,
            )

    def _enable_maintenance_notifications(
        self, maint_notifications_config: MaintNotificationsConfig, check_health=True
    ):
        try:
            host = getattr(self, "host", None)
            if host is None:
                raise ValueError(
                    "Cannot enable maintenance notifications for connection"
                    " object that doesn't have a host attribute."
                )
            else:
                endpoint_type = maint_notifications_config.get_endpoint_type(host, self)
                self.send_command(
                    "CLIENT",
                    "MAINT_NOTIFICATIONS",
                    "ON",
                    "moving-endpoint-type",
                    endpoint_type.value,
                    check_health=check_health,
                )
                response = self.read_response()
                if not response or str_if_bytes(response) != "OK":
                    raise ResponseError(
                        "The server doesn't support maintenance notifications"
                    )

View on GitHub (pinned to 6a6b581b48)