redis/redis-py · error · SlaveNotFoundError

No slave found for

Error message

No slave found for {self.service_name!r}

What it means

Raised as SlaveNotFoundError (a ConnectionError subclass) from SentinelConnectionPool.rotate_slaves after it discovers zero usable slaves for the service AND the fallback to discover_master also raises MasterNotFoundError. This means the slave-for() client has nowhere to send a read: no replicas and no master fallback. It is thrown when iterating slave addresses during connection establishment for a slave pool.

Solutions

  1. Verify with `redis-cli -p 26379 sentinel replicas <service_name>` that replicas exist and are not flagged down.
  2. Ensure at least one replica is configured and reachable; add replicas if none exist.
  3. Check Sentinel quorum and the service_name spelling.
  4. Temporarily read from master by using master_for() instead of slave_for().

Example fix

# before
slave = sentinel.slave_for('mymaster')
await slave.get('k')  # SlaveNotFoundError
# after
master = sentinel.master_for('mymaster')
await master.get('k')  # read from master until replicas recover
Defensive patterns

Strategy: fallback

Validate before calling

replicas = await sentinel.discover_slaves(service_name)
if not replicas:
    logger.warning("no replicas; falling back to master")

Try / catch

from redis.asyncio.sentinel import SlaveNotFoundError
try:
    return await slave_client.get(key)
except SlaveNotFoundError:
    return await sentinel.master_for(service_name).get(key)

Prevention

When it happens

Trigger: Opening/using a slave_for()/replica_for() client where discover_slaves() returns an empty list (all replicas down, in SDOWN/ODOWN, or none configured) and discover_master() also fails with MasterNotFoundError.

Common situations: All replicas are down or in ODOWN/SDOWN state. A fresh Sentinel deployment with no replicas attached to the service. Quorum loss so Sentinel cannot report master or slaves. service_name typo so Sentinel knows nothing about the service.

Related errors


AI-assisted analysis of redis/redis-py@6a6b581b48 (2026-08-10). Data as JSON: /api/errors/5521474ad685bffa. Report an issue: GitHub.

Appendix: 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 6a6b581b48)