redis/redis-py · error · DataError

SHUTDOWN save and nosave cannot both be set

Error message

SHUTDOWN save and nosave cannot both be set

What it means

Raised by shutdown() (redis/commands/core.py:2112) when both save=True and nosave=True are passed. The two flags are contradictory at the protocol level (SAVE forces a dump, NOSAVE skips it), so the library rejects the combination before sending. This is a redis.exceptions.DataError raised client-side. The other flags (now, force, abort) are independent.

Solutions

  1. Choose one: r.shutdown(save=True) to force a dump, or r.shutdown(nosave=True) to skip it
  2. If both come from config, enforce mutual exclusivity upstream and default the other to False
  3. Leave both False (the default) to honor the server's configured save points

Example fix

# before
r.shutdown(save=True, nosave=True)
# after
r.shutdown(save=True)
Defensive patterns

Strategy: validation

Validate before calling

if save and nosave:
    raise ValueError("save and nosave are mutually exclusive")
r.shutdown(save=save, nosave=nosave, now=now, force=force, abort=abort)

Try / catch

from redis.exceptions import DataError
try:
    r.shutdown(save=s, nosave=n)
except DataError as e:
    if "save and nosave cannot both be set" in str(e):
        r.shutdown(save=s)  # resolve conflict by preferring save
    else:
        raise

Prevention

When it happens

Trigger: Calling r.shutdown(save=True, nosave=True); or building flags from config where both accidentally resolve to True (e.g. inverted boolean logic).

Common situations: Mistakenly toggling both booleans; or a config schema that allows both to be set and forwards them straight through.

Related errors


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

Appendix: source

Thrown at redis/commands/core.py:2112

        force: bool = False,
        abort: bool = False,
        **kwargs,
    ) -> None:
        """Shutdown the Redis server.  If Redis has persistence configured,
        data will be flushed before shutdown.
        It is possible to specify modifiers to alter the behavior of the command:
        ``save`` will force a DB saving operation even if no save points are configured.
        ``nosave`` will prevent a DB saving operation even if one or more save points
        are configured.
        ``now`` skips waiting for lagging replicas, i.e. it bypasses the first step in
        the shutdown sequence.
        ``force`` ignores any errors that would normally prevent the server from exiting
        ``abort`` cancels an ongoing shutdown and cannot be combined with other flags.

        For more information, see https://redis.io/commands/shutdown
        """
        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.")

View on GitHub (pinned to 6a6b581b48)