{"record":{"id":"a27997c54ab275b7","repo":"redis/redis-py","slug":"cannot-enable-maintenance-notifications-for-connec-a27997","errorCode":null,"errorMessage":"Cannot enable maintenance notifications for connection object that doesn't have a host attribute.","messagePattern":"Cannot enable maintenance notifications for connection object that doesn't have a host attribute\\.","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"redis/connection.py","lineNumber":639,"sourceCode":"        if (\n            check_protocol_version(self.get_protocol(), 3)\n            and self.maint_notifications_config\n            and self.maint_notifications_config.enabled\n            and self._maint_notifications_connection_handler\n            and host is not None\n        ):\n            self._enable_maintenance_notifications(\n                maint_notifications_config=self.maint_notifications_config,\n                check_health=check_health,\n            )\n\n    def _enable_maintenance_notifications(\n        self, maint_notifications_config: MaintNotificationsConfig, check_health=True\n    ):\n        try:\n            host = getattr(self, \"host\", None)\n            if host is None:\n                raise ValueError(\n                    \"Cannot enable maintenance notifications for connection\"\n                    \" object that doesn't have a host attribute.\"\n                )\n            else:\n                endpoint_type = maint_notifications_config.get_endpoint_type(host, self)\n                self.send_command(\n                    \"CLIENT\",\n                    \"MAINT_NOTIFICATIONS\",\n                    \"ON\",\n                    \"moving-endpoint-type\",\n                    endpoint_type.value,\n                    check_health=check_health,\n                )\n                response = self.read_response()\n                if not response or str_if_bytes(response) != \"OK\":\n                    raise ResponseError(\n                        \"The server doesn't support maintenance notifications\"\n                    )","sourceCodeStart":621,"sourceCodeEnd":657,"githubUrl":"https://github.com/redis/redis-py/blob/6a6b581b48225afa0b76912d1028c6035baee932/redis/connection.py#L621-L657","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Do not enable maint_notifications_config on UnixDomainSocketConnection or any host-less connection — disable it (enabled=False) or leave the config unset.","If you wrote a custom Connection subclass, ensure it sets self.host (and exposes the host property) before on_connect runs.","Use a TCP Connection (redis.Connection / Redis(host=...)) when you need maintenance notifications.","Set maint_notifications_config.enabled='auto' only after confirming the transport is TCP."],"exampleFix":"# before\nr = redis.Redis(\n    unix_socket_path='/tmp/redis.sock',\n    protocol=3,\n    maint_notifications_config=MaintNotificationsConfig(enabled=True, ...),\n)\n# after\nr = redis.Redis(unix_socket_path='/tmp/redis.sock', protocol=3)  # no maint notifications","handlingStrategy":"validation","validationCode":"# before constructing the client\nproto = 3\nwant_maint = bool(maint_cfg and getattr(maint_cfg, 'enabled', False) in (True, 'auto'))\nis_tcp = transport in (None, 'tcp')\nif want_maint and not is_tcp:\n    raise ValueError('maintenance notifications require a TCP (host-based) connection')\nr = redis.Redis(host=h, port=p, protocol=proto,\n                maint_notifications_config=maint_cfg if (want_maint and is_tcp) else None)","typeGuard":"def supports_maint_notifications(conn) -> bool:\n    return getattr(conn, 'host', None) is not None and isinstance(\n        conn, MaintNotificationsAbstractConnection\n    )","tryCatchPattern":"try:\n    r = redis.Redis(unix_socket_path=p, protocol=3, maint_notifications_config=cfg)\n    r.ping()\nexcept ValueError as e:\n    if 'host attribute' in str(e):\n        # disable maint notifications and retry over UDS\n        r = redis.Redis(unix_socket_path=p, protocol=3)\n    else:\n        raise","preventionTips":["Keep maintenance notifications tied to TCP connections only.","Build the connection config from a single source that knows the transport.","In custom Connection subclasses, always set self.host if you intend to support maint notifications."],"tags":["maintenance-notifications","connection","configuration","uds"],"backgroundTag":null,"analyzedSha":"6a6b581b48225afa0b76912d1028c6035baee932","analyzedAt":"2026-08-10T12:52:44.840Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-21T04:17:39.646Z"}