{"id":"510feee8de97ce34","repo":"redis/redis-py","slug":"health-check-event-loop-failed-to-start-within-ti","errorCode":null,"errorMessage":"Health check event loop failed to start within {timeout} seconds","messagePattern":"Health check event loop failed to start within (.+?) seconds","errorType":"exception","errorClass":"RuntimeError","httpStatus":null,"severity":"error","filePath":"redis/background.py","lineNumber":254,"sourceCode":"            )\n            self._health_check_thread.start()\n\n            # Wait for loop to be running INSIDE the lock with a timeout.\n            # This prevents other threads from trying to create another loop\n            # before this one is fully started, while avoiding permanent deadlock\n            # if the background thread fails to start the loop.\n            if not self._health_check_loop_ready.wait(timeout=timeout):\n                # Timeout expired - the loop failed to start\n                # Clean up the failed loop to allow retry\n                failed_loop = self._health_check_loop\n                self._health_check_loop = None\n                if failed_loop in self._event_loops:\n                    self._event_loops.remove(failed_loop)\n                try:\n                    failed_loop.close()\n                except Exception:\n                    pass\n                raise RuntimeError(\n                    f\"Health check event loop failed to start within {timeout} seconds\"\n                )\n\n    def _run_health_check_loop(self):\n        \"\"\"Run the shared health check event loop.\"\"\"\n        asyncio.set_event_loop(self._health_check_loop)\n\n        # Signal that the loop is ready before running\n        # Use call_soon to signal after run_forever starts processing\n        self._health_check_loop.call_soon(self._health_check_loop_ready.set)\n\n        try:\n            self._health_check_loop.run_forever()\n        finally:\n            try:\n                pending = asyncio.all_tasks(self._health_check_loop)\n                for task in pending:\n                    task.cancel()","sourceCodeStart":236,"sourceCodeEnd":272,"githubUrl":"https://github.com/redis/redis-py/blob/da03cdc7e8731092b13e395605c3c1fb2de25de1/redis/background.py#L236-L272","documentation":"Raised as RuntimeError by BackgroundScheduler._ensure_health_check_loop (redis/background.py:254) when the dedicated health-check event loop does not signal readiness within the timeout (default 5s). The background thread either failed to start, failed to run the loop, or the system is too loaded for call_soon to fire promptly.","triggerScenarios":"run_coro_sync / run_recurring_coro / run_coro_fire_and_forget triggering _ensure_health_check_loop on a thread-starved or overloaded host; thread creation blocked by resource limits; the loop thread died before signaling readiness.","commonSituations":"Container/process at thread limit (RLIMIT_NPROC, cgroup pids.max); very high CPU load so the daemon thread never gets scheduled; thread creation blocked by seccomp/AppArmor; intermittent under heavy load spikes.","solutions":["Raise the timeout passed to _ensure_health_check_loop (call site) on loaded hosts.","Increase thread/process limits for the container/process (pids.max, RLIMIT_NPROC).","Reduce background CPU pressure or co-locate fewer busy loops on the same process.","Investigate why the daemon thread is not reaching run_forever (check for early thread death / exceptions in _run_health_check_loop)."],"exampleFix":"# before\nscheduler._ensure_health_check_loop()  # default timeout=5.0 may be too short\n# after\nscheduler._ensure_health_check_loop(timeout=15.0)","handlingStrategy":"try-catch","validationCode":"import resource\nsoft, hard = resource.getrlimit(resource.RLIMIT_NPROC)\nif soft != resource.RLIM_INFINITY and soft < 50:\n    logger.warning('thread limit low; health-check loop may not start')","typeGuard":null,"tryCatchPattern":"try:\n    scheduler._ensure_health_check_loop(timeout=15.0)\nexcept RuntimeError as e:\n    logger.error('health-check loop unavailable: %s', e)\n    raise","preventionTips":["Raise pids.max / RLIMIT_NPROC on busy hosts.","Tune the timeout upward on loaded systems."],"tags":["scheduler","threading","background","healthcheck"],"analyzedSha":"da03cdc7e8731092b13e395605c3c1fb2de25de1","analyzedAt":"2026-08-04T20:26:47.563Z","schemaVersion":2}