redis/redis-py · error · NotImplementedError

FAILOVER is intentionally not implemented in the client.

Error message

FAILOVER is intentionally not implemented in the client.

What it means

The FAILOVER command is intentionally not exposed by this client; calling client.failover() raises NotImplementedError immediately. Redis FAILOVER promotes a replica to primary, an operation the library deliberately leaves to ops tooling/sentinel rather than the data client. Use a lower-level command dispatch if you truly need it.

Source

Thrown at redis/commands/core.py:2301

        return self.execute_command(
            "WAITAOF", num_local, num_replicas, timeout, **kwargs
        )

    def hello(self):
        """
        This function throws a NotImplementedError since it is intentionally
        not supported.
        """
        raise NotImplementedError(
            "HELLO is intentionally not implemented in the client."
        )

    def failover(self):
        """
        This function throws a NotImplementedError since it is intentionally
        not supported.
        """
        raise NotImplementedError(
            "FAILOVER is intentionally not implemented in the client."
        )

    @overload
    def hotkeys_start(
        self: SyncClientProtocol,
        metrics: List[HotkeysMetricsTypes],
        count: int | None = None,
        duration: int | None = None,
        sample_ratio: int | None = None,
        slots: List[int] | None = None,
        **kwargs,
    ) -> bytes | str: ...

    @overload
    def hotkeys_start(
        self: AsyncClientProtocol,
        metrics: List[HotkeysMetricsTypes],

View on GitHub (pinned to da03cdc7e8)

Solutions

  1. Send the command manually via r.execute_command('FAILOVER') if you accept the operational risk and your server version supports it.
  2. Prefer Redis Sentinel (redis.sentinel.Sentinel) or your deployment's failover mechanism instead of issuing FAILOVER from the data client.
  3. Remove the failover() call from your application code path; failover is an infra concern, not a runtime data-path call.

Example fix

# before
await r.failover()

# after (only if you intentionally need raw dispatch)
await r.execute_command('FAILOVER')
Defensive patterns

Strategy: fallback

Validate before calling

import inspect
from redis.commands.core import CoreCommands

if 'failover' in dir(client):
    # method exists but always raises; check intent before calling
    raise RuntimeError('failover() is intentionally unsupported; use execute_command or sentinel')

Type guard

def supports_failover(client) -> bool:
    # The method exists but raises NotImplementedError by design.
    return False

Try / catch

from redis.exceptions import RedisError
try:
    await client.failover()
except NotImplementedError:
    # intentional: dispatch raw command if you accept the risk
    await client.execute_command('FAILOVER')
except RedisError:
    raise

Prevention

When it happens

Trigger: Calling r.failover() or await r.failover() on a Redis/RedisCluster instance. The method exists (in CoreCommands) purely to fail loudly rather than silently sending an unsupported command.

Common situations: Migrating from another client that exposed failover, building HA/failover orchestration logic in-app, or copy-pasting CLI recipes into Python code. Developers assume every Redis command has a Python wrapper.

Related errors


AI-assisted analysis of redis/redis-py@da03cdc7e8 (2026-08-04). Data as JSON: /data/errors/be428b063b84fa7f.json. Report an issue: GitHub.