{"id":"b79e91718f8a3e33","repo":"redis/redis-py","slug":"no-slave-found-for-self-service-name-r-b79e91","errorCode":null,"errorMessage":"No slave found for {self.service_name!r}","messagePattern":"No slave found for (.+?)","errorType":"exception","errorClass":"SlaveNotFoundError","httpStatus":null,"severity":"error","filePath":"redis/sentinel.py","lineNumber":144,"sourceCode":"            if connection_pool is not None:\n                connection_pool.disconnect(inuse_connections=False)\n        return master_address\n\n    def rotate_slaves(self):\n        slaves = self.sentinel_manager.discover_slaves(self.service_name)\n        if slaves:\n            if self.slave_rr_counter is None:\n                self.slave_rr_counter = random.randint(0, len(slaves) - 1)\n            for _ in range(len(slaves)):\n                self.slave_rr_counter = (self.slave_rr_counter + 1) % len(slaves)\n                slave = slaves[self.slave_rr_counter]\n                yield slave\n        # Fallback to the master connection\n        try:\n            yield self.get_master_address()\n        except MasterNotFoundError:\n            pass\n        raise SlaveNotFoundError(f\"No slave found for {self.service_name!r}\")\n\n    def rotate_replicas(self):\n        \"\"\"Round-robin replica balancer.\n\n        This is an alias for :py:meth:`rotate_slaves`,\n        using the preferred Redis 5.0+ terminology.\n        \"\"\"\n        return self.rotate_slaves()\n\n\nclass SentinelConnectionPool(ConnectionPool):\n    \"\"\"\n    Sentinel backed connection pool.\n\n    If ``check_connection`` flag is set to True, SentinelManagedConnection\n    sends a PING command right after establishing the connection.\n    \"\"\"\n","sourceCodeStart":126,"sourceCodeEnd":162,"githubUrl":"https://github.com/redis/redis-py/blob/da03cdc7e8731092b13e395605c3c1fb2de25de1/redis/sentinel.py#L126-L162","documentation":"Raised by SentinelConnectionPoolProxy.rotate_slaves (redis/sentinel.py:144) as redis.exceptions.SlaveNotFoundError (a ConnectionError subclass). When building a replica connection, the pool round-robins through discovered replicas; if none can be connected to, it falls back to the master address via get_master_address(). If that fallback also raises MasterNotFoundError, the loop exits and SlaveNotFoundError is raised with the service name.","triggerScenarios":"Calling commands through a connection obtained via Sentinel.slave_for(...) / Sentinel.replica_for(...) when discover_slaves() returns an empty list or every discovered replica is unreachable (filter_slaves removed them, or connect_to raised ConnectionError for each), and the master fallback in rotate_slaves also fails (MasterNotFoundError caught at line 142).","commonSituations":"All replicas down or in ODOWN/SDOWN state; Sentinel has not yet learned the replica topology after a fresh deployment; network partition isolating the client from replicas but the master discovery path also failing; misconfigured service_name.","solutions":["Verify replica health from a Sentinel: redis-cli -p <sentinel_port> sentinel replicas <service_name>.","Fall back to master_for(...) for reads when replicas are unavailable (read-your-writes permitting).","Confirm Sentinel quorum is healthy and that Sentinels can see replicas.","Check network connectivity / firewall rules between the client and replica ports."],"exampleFix":"# before\nreader = sentinel.slave_for('mymaster')\ndata = reader.get('k')\n# after\nfrom redis.sentinel import SlaveNotFoundError\nfrom redis.exceptions import ConnectionError\ntry:\n    reader = sentinel.slave_for('mymaster')\n    data = reader.get('k')\nexcept (SlaveNotFoundError, ConnectionError):\n    reader = sentinel.master_for('mymaster')\n    data = reader.get('k')","handlingStrategy":"fallback","validationCode":"def replicas_available(sentinel, service_name: str) -> bool:\n    return len(sentinel.discover_slaves(service_name)) > 0\n\n# Choose reader based on availability\nreader = (sentinel.slave_for(name) if replicas_available(sentinel, name)\n          else sentinel.master_for(name))","typeGuard":null,"tryCatchPattern":"from redis.sentinel import SlaveNotFoundError\nfrom redis.exceptions import ConnectionError as RedisConnectionError\n\ntry:\n    reader = sentinel.slave_for('mymaster')\n    data = reader.get('k')\nexcept (SlaveNotFoundError, RedisConnectionError):\n    # Fall back to master for reads when replicas are unavailable\n    reader = sentinel.master_for('mymaster')\n    data = reader.get('k')","preventionTips":["Always provide a master_for() fallback when reading via slave_for().","Monitor replica counts via `sentinel replicas <name>` and alert when they drop to zero.","Validate Sentinel quorum health as part of deployment runbooks.","Cache the discovery result briefly to avoid hammering Sentinel on every read."],"tags":["sentinel","replica","replication","topology","failover"],"analyzedSha":"da03cdc7e8731092b13e395605c3c1fb2de25de1","analyzedAt":"2026-08-04T20:26:47.563Z","schemaVersion":2}