{"id":"5521474ad685bffa","repo":"redis/redis-py","slug":"no-slave-found-for-self-service-name-r","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/asyncio/sentinel.py","lineNumber":170,"sourceCode":"                await self.disconnect(inuse_connections=False)\n        return master_address\n\n    async def rotate_slaves(self) -> AsyncIterator:\n        \"\"\"Round-robin slave balancer\"\"\"\n        slaves = await 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 await 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) -> AsyncIterator:\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 Sentinel(AsyncSentinelCommands):\n    \"\"\"\n    Redis Sentinel cluster client\n\n    >>> from redis.sentinel import Sentinel\n    >>> sentinel = Sentinel([('localhost', 26379)], socket_timeout=0.1)\n    >>> master = sentinel.master_for('mymaster', socket_timeout=0.1)\n    >>> await master.set('foo', 'bar')","sourceCodeStart":152,"sourceCodeEnd":188,"githubUrl":"https://github.com/redis/redis-py/blob/da03cdc7e8731092b13e395605c3c1fb2de25de1/redis/asyncio/sentinel.py#L152-L188","documentation":"Raised as SlaveNotFoundError from SentinelConnectionPool.rotate_slaves (redis/asyncio/sentinel.py:170) when Sentinel reports zero alive replicas for the service and master discovery also yields nothing (MasterNotFoundError is swallowed). The round-robin replica balancer has exhausted every option, so a read against a slave_for(...) client cannot be served.","triggerScenarios":"Calling a read command on a slave_for(...) client when all replicas are in SDOWN/ODOWN or none are configured; replicas removed from the topology while reads are in flight.","commonSituations":"All replicas down or under maintenance; a single-node deployment with no replicas used with slave_for; failover window where replicas have not yet been promoted/reported.","solutions":["Allow the read to fall back to the master (rotate_slaves already tries master discovery; ensure discover_master can succeed).","Scale/restore replica nodes so Sentinel reports at least one healthy replica.","Retry with backoff during transient replica unavailability."],"exampleFix":"# before\nval = await slave.get('k')  # SlaveNotFoundError if no replicas\n# after\ntry:\n    val = await slave.get('k')\nexcept SlaveNotFoundError:\n    val = await master.get('k')  # graceful fallback","handlingStrategy":"fallback","validationCode":"replicas = await sentinel.discover_slaves(service_name)\nif not replicas:\n    use_master_fallback = True","typeGuard":null,"tryCatchPattern":"from redis.sentinel import SlaveNotFoundError\ntry:\n    return await slave_client.get(key)\nexcept SlaveNotFoundError:\n    return await master_client.get(key)","preventionTips":["Design reads to fall back to master when replicas are unavailable.","Monitor replica count via discover_slaves and alert before it hits zero."],"tags":["sentinel","replicas","failover"],"analyzedSha":"da03cdc7e8731092b13e395605c3c1fb2de25de1","analyzedAt":"2026-08-04T20:26:47.563Z","schemaVersion":2}