{"id":"be428b063b84fa7f","repo":"redis/redis-py","slug":"failover-is-intentionally-not-implemented-in-the-c","errorCode":null,"errorMessage":"FAILOVER is intentionally not implemented in the client.","messagePattern":"FAILOVER is intentionally not implemented in the client\\.","errorType":"exception","errorClass":"NotImplementedError","httpStatus":null,"severity":"error","filePath":"redis/commands/core.py","lineNumber":2301,"sourceCode":"        return self.execute_command(\n            \"WAITAOF\", num_local, num_replicas, timeout, **kwargs\n        )\n\n    def hello(self):\n        \"\"\"\n        This function throws a NotImplementedError since it is intentionally\n        not supported.\n        \"\"\"\n        raise NotImplementedError(\n            \"HELLO is intentionally not implemented in the client.\"\n        )\n\n    def failover(self):\n        \"\"\"\n        This function throws a NotImplementedError since it is intentionally\n        not supported.\n        \"\"\"\n        raise NotImplementedError(\n            \"FAILOVER is intentionally not implemented in the client.\"\n        )\n\n    @overload\n    def hotkeys_start(\n        self: SyncClientProtocol,\n        metrics: List[HotkeysMetricsTypes],\n        count: int | None = None,\n        duration: int | None = None,\n        sample_ratio: int | None = None,\n        slots: List[int] | None = None,\n        **kwargs,\n    ) -> bytes | str: ...\n\n    @overload\n    def hotkeys_start(\n        self: AsyncClientProtocol,\n        metrics: List[HotkeysMetricsTypes],","sourceCodeStart":2283,"sourceCodeEnd":2319,"githubUrl":"https://github.com/redis/redis-py/blob/da03cdc7e8731092b13e395605c3c1fb2de25de1/redis/commands/core.py#L2283-L2319","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Send the command manually via r.execute_command('FAILOVER') if you accept the operational risk and your server version supports it.","Prefer Redis Sentinel (redis.sentinel.Sentinel) or your deployment's failover mechanism instead of issuing FAILOVER from the data client.","Remove the failover() call from your application code path; failover is an infra concern, not a runtime data-path call."],"exampleFix":"# before\nawait r.failover()\n\n# after (only if you intentionally need raw dispatch)\nawait r.execute_command('FAILOVER')","handlingStrategy":"fallback","validationCode":"import inspect\nfrom redis.commands.core import CoreCommands\n\nif 'failover' in dir(client):\n    # method exists but always raises; check intent before calling\n    raise RuntimeError('failover() is intentionally unsupported; use execute_command or sentinel')","typeGuard":"def supports_failover(client) -> bool:\n    # The method exists but raises NotImplementedError by design.\n    return False","tryCatchPattern":"from redis.exceptions import RedisError\ntry:\n    await client.failover()\nexcept NotImplementedError:\n    # intentional: dispatch raw command if you accept the risk\n    await client.execute_command('FAILOVER')\nexcept RedisError:\n    raise","preventionTips":["Do not call client.failover(); treat failover as an infra/sentinel concern.","If raw dispatch is required, gate it behind an explicit ops flag, not a default code path."],"tags":["redis","notimplemented","failover","operations","intentional"],"analyzedSha":"da03cdc7e8731092b13e395605c3c1fb2de25de1","analyzedAt":"2026-08-04T20:26:47.563Z","schemaVersion":2}