{"id":"b088730f62001e01","repo":"redis/redis-py","slug":"shutdown-seems-to-have-failed","errorCode":null,"errorMessage":"SHUTDOWN seems to have failed.","messagePattern":"SHUTDOWN seems to have failed\\.","errorType":"exception","errorClass":"RedisError","httpStatus":null,"severity":"error","filePath":"redis/commands/core.py","lineNumber":2129,"sourceCode":"        if save and nosave:\n            raise DataError(\"SHUTDOWN save and nosave cannot both be set\")\n        args = [\"SHUTDOWN\"]\n        if save:\n            args.append(\"SAVE\")\n        if nosave:\n            args.append(\"NOSAVE\")\n        if now:\n            args.append(\"NOW\")\n        if force:\n            args.append(\"FORCE\")\n        if abort:\n            args.append(\"ABORT\")\n        try:\n            self.execute_command(*args, **kwargs)\n        except ConnectionError:\n            # a ConnectionError here is expected\n            return\n        raise RedisError(\"SHUTDOWN seems to have failed.\")\n\n    @overload\n    def slaveof(\n        self: SyncClientProtocol,\n        host: str | None = None,\n        port: int | None = None,\n        **kwargs,\n    ) -> bool: ...\n\n    @overload\n    def slaveof(\n        self: AsyncClientProtocol,\n        host: str | None = None,\n        port: int | None = None,\n        **kwargs,\n    ) -> Awaitable[bool]: ...\n\n    def slaveof(","sourceCodeStart":2111,"sourceCodeEnd":2147,"githubUrl":"https://github.com/redis/redis-py/blob/da03cdc7e8731092b13e395605c3c1fb2de25de1/redis/commands/core.py#L2111-L2147","documentation":"Raised as a RedisError by shutdown after the command executes WITHOUT raising a ConnectionError. A successful SHUTDOWN kills the server, so the connection is always dropped and a ConnectionError is expected and caught (the method returns normally). If no ConnectionError occurred, the shutdown did not complete as expected, so a RedisError is raised.","triggerScenarios":"The server responded to SHUTDOWN without closing the connection (unexpected server behavior). A network proxy or connection pool intercepted and suppressed the disconnect. The server was configured to ignore SHUTDOWN (e.g., via rename-command).","commonSituations":"Running behind a proxy (Twemproxy, Envoy) that keeps the connection alive. Server version or config that doesn't actually shut down. Mock/fake Redis in tests that doesn't drop the connection.","solutions":["Verify the Redis server actually shut down (e.g., check process or port).","If behind a proxy, connect directly to the Redis node for SHUTDOWN.","In test environments using a mock server, expect and handle this error or mock the ConnectionError."],"exampleFix":"# before\nr.shutdown()  # raises RedisError in test/mock env\n# after\ntry:\n    r.shutdown()\nexcept RedisError:\n    # connection wasn't dropped — verify server state externally\n    pass","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"from redis.exceptions import RedisError, ConnectionError\ntry:\n    r.shutdown()\nexcept ConnectionError:\n    pass  # expected — server is shutting down\nexcept RedisError:\n    # shutdown did not behave as expected — investigate\n    log.warning('SHUTDOWN did not drop the connection')","preventionTips":["A successful SHUTDOWN always drops the connection; the absence of that error is the anomaly.","When using proxies or mock servers, SHUTDOWN behavior may differ — connect directly for real shutdowns."],"tags":["server-management","shutdown","connection","rediserror"],"analyzedSha":"da03cdc7e8731092b13e395605c3c1fb2de25de1","analyzedAt":"2026-08-04T20:26:47.563Z","schemaVersion":2}