redis/redis-py · error · RedisError

SHUTDOWN seems to have failed.

Error message

SHUTDOWN seems to have failed.

What it means

Raised by shutdown() (redis/commands/core.py:2129) after the SHUTDOWN command returns WITHOUT raising a ConnectionError. The expected success path is that the server closes the connection during shutdown, surfacing as a ConnectionError that the method swallows and returns normally; if execute_command returns at all, the library assumes the server is still alive and raises a redis.exceptions.RedisError. This typically happens with SHUTDOWN ABORT (which cancels an in-progress shutdown and returns OK), with certain NOW/FORCE combinations, or when a replica/ACL guard prevents the shutdown.

Solutions

  1. If you intended to abort, wrap the call: try: r.shutdown(abort=True) except RedisError: pass
  2. Verify the user has the admin/shutdown ACL permission before calling
  3. For a real shutdown, ensure no abort flag and that the target is a writable master; expect ConnectionError as the normal outcome
  4. Check server logs / replica lag if shutdown is being blocked by min-replicas configuration

Example fix

# before
r.shutdown(abort=True)  # raises RedisError because server replied OK
# after
from redis.exceptions import RedisError
try:
    r.shutdown(abort=True)
except RedisError:
    pass  # abort returns a reply rather than closing the connection
Defensive patterns

Strategy: try-catch

Validate before calling

# Pre-check ACL for shutdown permission when feasible
me = r.execute_command("ACL", "WHOAMI")
# also detect abort mode, which legitimately returns a reply
if abort:
    # SHUTDOWN ABORT returns OK instead of closing the connection
    expected_reply = True

Try / catch

from redis.exceptions import RedisError, ConnectionError
try:
    r.shutdown(save=save, nosave=nosave, abort=abort)
except ConnectionError:
    pass  # normal: server closed the connection during shutdown
except RedisError as e:
    if "SHUTDOWN seems to have failed" in str(e):
        # server replied instead of closing (e.g. SHUTDOWN ABORT) - inspect logs
        pass
    else:
        raise

Prevention

When it happens

Trigger: Calling r.shutdown(abort=True) (server returns OK instead of closing the link); calling shutdown against a node protected by min-replicas/ACL that rejects the operation; or a Redis version whose shutdown path returns a reply rather than dropping the connection.

Common situations: Using abort=True to cancel a shutdown in failover tests; running shutdown against a managed/Redis Cloud endpoint that intercepts it; the connection being proxied so the close is masked.

Related errors


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

Appendix: source

Thrown at redis/commands/core.py:2129

        if save and nosave:
            raise DataError("SHUTDOWN save and nosave cannot both be set")
        args = ["SHUTDOWN"]
        if save:
            args.append("SAVE")
        if nosave:
            args.append("NOSAVE")
        if now:
            args.append("NOW")
        if force:
            args.append("FORCE")
        if abort:
            args.append("ABORT")
        try:
            self.execute_command(*args, **kwargs)
        except ConnectionError:
            # a ConnectionError here is expected
            return
        raise RedisError("SHUTDOWN seems to have failed.")

    @overload
    def slaveof(
        self: SyncClientProtocol,
        host: str | None = None,
        port: int | None = None,
        **kwargs,
    ) -> bool: ...

    @overload
    def slaveof(
        self: AsyncClientProtocol,
        host: str | None = None,
        port: int | None = None,
        **kwargs,
    ) -> Awaitable[bool]: ...

    def slaveof(

View on GitHub (pinned to 6a6b581b48)