redis/redis-py · error · SlaveNotFoundError
No slave found for {self.service_name!r}
Error message
No slave found for {self.service_name!r} What it means
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.
Source
Thrown at redis/asyncio/sentinel.py:170
await self.disconnect(inuse_connections=False)
return master_address
async def rotate_slaves(self) -> AsyncIterator:
"""Round-robin slave balancer"""
slaves = await self.sentinel_manager.discover_slaves(self.service_name)
if slaves:
if self.slave_rr_counter is None:
self.slave_rr_counter = random.randint(0, len(slaves) - 1)
for _ in range(len(slaves)):
self.slave_rr_counter = (self.slave_rr_counter + 1) % len(slaves)
slave = slaves[self.slave_rr_counter]
yield slave
# Fallback to the master connection
try:
yield await self.get_master_address()
except MasterNotFoundError:
pass
raise SlaveNotFoundError(f"No slave found for {self.service_name!r}")
def rotate_replicas(self) -> AsyncIterator:
"""Round-robin replica balancer.
This is an alias for :py:meth:`rotate_slaves`,
using the preferred Redis 5.0+ terminology.
"""
return self.rotate_slaves()
class Sentinel(AsyncSentinelCommands):
"""
Redis Sentinel cluster client
>>> from redis.sentinel import Sentinel
>>> sentinel = Sentinel([('localhost', 26379)], socket_timeout=0.1)
>>> master = sentinel.master_for('mymaster', socket_timeout=0.1)
>>> await master.set('foo', 'bar')View on GitHub (pinned to da03cdc7e8)
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.
Example fix
# before
val = await slave.get('k') # SlaveNotFoundError if no replicas
# after
try:
val = await slave.get('k')
except SlaveNotFoundError:
val = await master.get('k') # graceful fallback Defensive patterns
Strategy: fallback
Validate before calling
replicas = await sentinel.discover_slaves(service_name)
if not replicas:
use_master_fallback = True Try / catch
from redis.sentinel import SlaveNotFoundError
try:
return await slave_client.get(key)
except SlaveNotFoundError:
return await master_client.get(key) Prevention
- Design reads to fall back to master when replicas are unavailable.
- Monitor replica count via discover_slaves and alert before it hits zero.
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- The previous master is now a slave
- No master found for {service_name!r}{error_info}
- The previous master is now a slave
- No slave found for {self.service_name!r}
- No master found for {service_name!r}{error_info}
AI-assisted analysis of redis/redis-py@da03cdc7e8 (2026-08-04).
Data as JSON: /data/errors/5521474ad685bffa.json.
Report an issue: GitHub.