{"id":"3d297feb3a284f64","repo":"redis/redis-py","slug":"no-master-found-for-service-name-r-error-info-3d297f","errorCode":null,"errorMessage":"No master found for {service_name!r}{error_info}","messagePattern":"No master found for (.+?)(.+?)","errorType":"exception","errorClass":"MasterNotFoundError","httpStatus":null,"severity":"critical","filePath":"redis/sentinel.py","lineNumber":384,"sourceCode":"            state = masters.get(service_name)\n            if state and self.check_master_state(state, service_name):\n                # Put this sentinel at the top of the list\n                self.sentinels[0], self.sentinels[sentinel_no] = (\n                    sentinel,\n                    self.sentinels[0],\n                )\n\n                ip = (\n                    self._force_master_ip\n                    if self._force_master_ip is not None\n                    else state[\"ip\"]\n                )\n                return ip, state[\"port\"]\n\n        error_info = \"\"\n        if len(collected_errors) > 0:\n            error_info = f\" : {', '.join(collected_errors)}\"\n        raise MasterNotFoundError(f\"No master found for {service_name!r}{error_info}\")\n\n    def filter_slaves(self, slaves):\n        \"Remove slaves that are in an ODOWN or SDOWN state\"\n        slaves_alive = []\n        for slave in slaves:\n            if slave[\"is_odown\"] or slave[\"is_sdown\"]:\n                continue\n            slaves_alive.append((slave[\"ip\"], slave[\"port\"]))\n        return slaves_alive\n\n    def filter_replicas(self, replicas):\n        \"\"\"Remove replicas that are in an ODOWN or SDOWN state.\n\n        This is an alias for :py:meth:`filter_slaves`,\n        using the preferred Redis 5.0+ terminology.\n        \"\"\"\n        return self.filter_slaves(replicas)\n","sourceCodeStart":366,"sourceCodeEnd":402,"githubUrl":"https://github.com/redis/redis-py/blob/da03cdc7e8731092b13e395605c3c1fb2de25de1/redis/sentinel.py#L366-L402","documentation":"Raised by Sentinel.discover_master (redis/sentinel.py:384) as redis.exceptions.MasterNotFoundError (a ConnectionError subclass). The method iterates over every configured Sentinel, calls sentinel_masters(), and looks for a matching service_name whose state passes check_master_state. If no Sentinel yields a healthy master, MasterNotFoundError is raised; when some Sentinels were themselves unreachable, error_info lists the per-Sentinel ConnectionError/TimeoutError details.","triggerScenarios":"Any master_for(...) call or write operation on a Sentinel-managed client, when none of the configured Sentinels reports a valid master for the service_name (state missing, or check_master_state fails flags like master_flag, role, etc.). Also triggered when all Sentinels are unreachable, in which case error_info enumerates each failure.","commonSituations":"Wrong service_name (typo, or not yet monitored); all Sentinels down or unreachable from the client; master is down and Sentinel has not yet elected a new one; Sentinel lost quorum (s_down/o_down without promotion); network partition between client and Sentinels; Sentinel monitoring not yet bootstrapped for the deployment.","solutions":["Verify the service_name matches a monitored master: redis-cli -p <sentinel_port> sentinel masters.","Check Sentinel reachability and health from the client host (redis-cli -p <sentinel_port> ping).","Inspect Sentinel logs for s_down/o_down/failover events and confirm quorum is intact.","Confirm Sentinel knows the correct master: redis-cli -p <sentinel_port> sentinel get-master-addr-by-name <service_name>.","If a failover is in progress, wait and retry with backoff."],"exampleFix":"# before\nmaster = sentinel.master_for('mymaster')\nmaster.set('k', 'v')\n# after (validate name + retry with backoff)\nfrom redis.exceptions import ConnectionError\nimport time\nfor attempt in range(10):\n    try:\n        master = sentinel.master_for('mymaster')\n        master.set('k', 'v')\n        break\n    except ConnectionError:\n        time.sleep(0.2 * (2 ** attempt))","handlingStrategy":"retry","validationCode":"def master_discoverable(sentinel, service_name: str) -> bool:\n    try:\n        return sentinel.discover_master(service_name) is not None\n    except Exception:\n        return False","typeGuard":null,"tryCatchPattern":"import time\nfrom redis.exceptions import ConnectionError as RedisConnectionError\n\ndef get_master_with_retry(sentinel, name: str, max_attempts=10):\n    last_err = None\n    for attempt in range(max_attempts):\n        try:\n            return sentinel.master_for(name)\n        except RedisConnectionError as e:\n            last_err = e\n            time.sleep(0.2 * (2 ** attempt))\n    raise last_err","preventionTips":["Verify service_name spelling matches a monitored master before deploying.","Run periodic health checks against all configured Sentinels from the client host.","Keep Sentinels in odd numbers across failure domains to preserve quorum.","Wire retry-with-backoff around master_for() at the application boundary.","Alert on Sentinel s_down/o_down events to catch failover stalls early."],"tags":["sentinel","master","topology","replication","failover","availability"],"analyzedSha":"da03cdc7e8731092b13e395605c3c1fb2de25de1","analyzedAt":"2026-08-04T20:26:47.563Z","schemaVersion":2}