redis/redis-py · error · RedisError

Invalid option for CLUSTER FAILOVER command

Error message

Invalid option for CLUSTER FAILOVER command: {option}

What it means

Raised by ClusterManagementCommands.cluster_failover() in redis/commands/cluster.py:644 as a RedisError when the option argument is not one of the two valid values FORCE or TAKEOVER (case-insensitive). The CLUSTER FAILOVER command accepts only those options or none, so any other string is rejected before sending.

Solutions

  1. Pass option='FORCE', option='TAKEOVER', or option=None only.
  2. Strip/upper-case user input before passing: option=value.strip().upper() if value else None.
  3. Validate the option against {'FORCE','TAKEOVER'} before calling.

Example fix

// before
rc.cluster_failover(node, option='SYNC')
// after
rc.cluster_failover(node, option='FORCE')
Defensive patterns

Strategy: validation

Validate before calling

VALID = {None, 'FORCE', 'TAKEOVER'}
option = option.strip().upper() if isinstance(option, str) else option
assert option in VALID, f'option must be one of {VALID}'
rc.cluster_failover(node, option=option)

Type guard

def is_valid_failover_option(option) -> bool:
    if option is None:
        return True
    return isinstance(option, str) and option.strip().upper() in {'FORCE','TAKEOVER'}

Try / catch

from redis.exceptions import RedisError
try:
    rc.cluster_failover(node, option=option)
except RedisError as e:
    if 'Invalid option for CLUSTER FAILOVER' in str(e):
        rc.cluster_failover(node, option='FORCE')

Prevention

When it happens

Trigger: Calling rc.cluster_failover(target_node, option='SYNC'), option='async', option=True, or any value other than 'FORCE'/'TAKEOVER'/None.

Common situations: Typos in the option string; passing a boolean or non-string; mismatched casing assumptions beyond upper/lower; passing 'FORCE ' with trailing whitespace.

Related errors


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

Appendix: source

Thrown at redis/commands/cluster.py:644

        target_node: "TargetNodesT",
        option: str | None = None,
    ) -> Awaitable[bool]: ...

    def cluster_failover(
        self, target_node: "TargetNodesT", option: str | None = None
    ) -> bool | Awaitable[bool]:
        """
        Forces a slave to perform a manual failover of its master
        Sends to specified node

        :target_node: 'ClusterNode'
            The node to execute the command on

        For more information see https://redis.io/commands/cluster-failover
        """
        if option:
            if option.upper() not in ["FORCE", "TAKEOVER"]:
                raise RedisError(
                    f"Invalid option for CLUSTER FAILOVER command: {option}"
                )
            else:
                return self.execute_command(
                    "CLUSTER FAILOVER", option, target_nodes=target_node
                )
        else:
            return self.execute_command("CLUSTER FAILOVER", target_nodes=target_node)

    @overload
    def cluster_info(
        self: SyncClientProtocol, target_nodes: "TargetNodesT" | None = None
    ) -> dict[str, str]: ...

    @overload
    def cluster_info(
        self: AsyncClientProtocol, target_nodes: "TargetNodesT" | None = None
    ) -> Awaitable[dict[str, str]]: ...

View on GitHub (pinned to 6a6b581b48)