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
- Choose one: r.shutdown(save=True) to force a dump, or r.shutdown(nosave=True) to skip it
- If both come from config, enforce mutual exclusivity upstream and default the other to False
- 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
- Treat save/nosave as mutually exclusive radio options in config.
- Validate the pair at the config boundary, not at the call site.
- Default both to False to honor the server's own save policy.
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
- bit must be 0 or 1
- Both start and end must be specified
- ``byfloat`` and ``byint`` are mutually exclusive.
- client_id must be a list
- CLIENT KILL ... ... must specify at least one filter
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)