{"record":{"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/6a6b581b48225afa0b76912d1028c6035baee932/redis/sentinel.py#L126-L162","documentation":"Raised by SentinelConnectionPoolProxy.rotate_slaves() (redis/sentinel.py:144) when no replica is available to serve reads. rotate_slaves() first calls discover_slaves(service_name); if that returns an empty list (no replicas configured, or all filtered out as ODOWN/SDOWN via filter_slaves), the generator falls back to the master via get_master_address(); if THAT also raises MasterNotFoundError, the loop ends and SlaveNotFoundError is raised. So the client found neither a healthy replica nor a usable master fallback.","triggerScenarios":"Using slave_for(service_name) (read-only replica routing), the read connection pool calls rotate_slaves() to pick a replica; discover_slaves() yields nothing; the master fallback at sentinel.py:141 raises MasterNotFoundError (caught at 142); execution falls through to `raise SlaveNotFoundError(f\"No slave found for {self.service_name!r}\")`.","commonSituations":"Single-node Sentinel deployment with no replicas configured; all replicas simultaneously down or in SDOWN/ODOWN; during a failover where neither replicas nor a master is currently up; replicas exist but are all flagged subjectively down; service_name typo so discover_slaves returns [].","solutions":["Ensure at least one healthy replica exists for the service: check `redis-cli -p <sentinel_port> SENTINEL replicas <name>`.","Confirm service_name matches a monitored master with replicas attached.","During transient outages, catch SlaveNotFoundError and fall back to master_for() for reads or retry with backoff.","Add replicas to the topology if read scaling is required."],"exampleFix":"# before: read client fails when no replica is reachable\nslave = sentinel.slave_for('mymaster')\nslave.get('k')  # SlaveNotFoundError: No slave found for 'mymaster'\n\n# after: fall back to the master for reads when no replica is available\ntry:\n    slave.get('k')\nexcept redis.exceptions.SlaveNotFoundError:\n    sentinel.master_for('mymaster').get('k')","handlingStrategy":"fallback","validationCode":"def replicas_available(sentinel, service_name) -> bool:\n    # call before routing a read to a replica\n    return len(sentinel.discover_slaves(service_name)) > 0\n\n# if not replicas_available(sentinel, 'mymaster'): route read to master_for(...)","typeGuard":null,"tryCatchPattern":"import redis.exceptions\n\ndef read_with_replica_fallback(slave_client, master_client, op, *args, **kw):\n    try:\n        return op(slave_client, *args, **kw)\n    except redis.exceptions.SlaveNotFoundError:\n        # no replica available; degrade to master for this read\n        return op(master_client, *args, **kw)\n\n# usage:\n# read_with_replica_fallback(slave, master, lambda c, k: c.get(k), 'k')","preventionTips":["Provision at least one replica per monitored master if you use slave_for().","Pre-check discover_slaves() count before routing reads to replicas in critical paths.","Keep a master_for() client handy as a read fallback during replica outages."],"tags":["sentinel","replica","read-routing","high-availability"],"backgroundTag":null,"analyzedSha":"6a6b581b48225afa0b76912d1028c6035baee932","analyzedAt":"2026-08-10T12:52:44.840Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-21T04:17:39.646Z"}