{"id":"79b00ee8bf2de581","repo":"redis/redis-py","slug":"unable-to-acquire-lock-within-the-time-specified","errorCode":null,"errorMessage":"Unable to acquire lock within the time specified","messagePattern":"Unable to acquire lock within the time specified","errorType":"exception","errorClass":"LockError","httpStatus":null,"severity":"warning","filePath":"redis/asyncio/lock.py","lineNumber":173,"sourceCode":"        self.local = threading.local() if self.thread_local else SimpleNamespace()\n        self.raise_on_release_error = raise_on_release_error\n        self.local.token = None\n        self.register_scripts()\n\n    def register_scripts(self):\n        cls = self.__class__\n        client = self.redis\n        if cls.lua_release is None:\n            cls.lua_release = client.register_script(cls.LUA_RELEASE_SCRIPT)\n        if cls.lua_extend is None:\n            cls.lua_extend = client.register_script(cls.LUA_EXTEND_SCRIPT)\n        if cls.lua_reacquire is None:\n            cls.lua_reacquire = client.register_script(cls.LUA_REACQUIRE_SCRIPT)\n\n    async def __aenter__(self):\n        if await self.acquire():\n            return self\n        raise LockError(\"Unable to acquire lock within the time specified\")\n\n    async def __aexit__(self, exc_type, exc_value, traceback):\n        try:\n            await self.release()\n        except LockError:\n            if self.raise_on_release_error:\n                raise\n            logger.warning(\n                \"Lock was unlocked or no longer owned when exiting context manager.\"\n            )\n\n    async def acquire(\n        self,\n        blocking: Optional[bool] = None,\n        blocking_timeout: Optional[Number] = None,\n        token: Optional[Union[str, bytes]] = None,\n    ):\n        \"\"\"","sourceCodeStart":155,"sourceCodeEnd":191,"githubUrl":"https://github.com/redis/redis-py/blob/da03cdc7e8731092b13e395605c3c1fb2de25de1/redis/asyncio/lock.py#L155-L191","documentation":"Raised as LockError by Lock.__aenter__ when acquire() returns False, i.e., the lock could not be obtained before blocking_timeout elapsed (or immediately if blocking=False). This is the context-manager equivalent of a failed acquire: 'async with lock:' translates a False return into this exception.","triggerScenarios":"Using 'async with lock:' where the lock is held by another owner for longer than the configured blocking_timeout, or blocking=False and the lock is currently held. acquire() returns False and __aenter__ raises at lock.py:173.","commonSituations":"High lock contention; a deadlock or long critical section; blocking_timeout too short; an owner that crashed without releasing (until the TTL expires); using the context manager where you wanted non-blocking semantics.","solutions":["Increase blocking_timeout (or the lock timeout) to tolerate contention.","Ensure critical sections are short and always release the lock.","Handle the failure path: acquire(blocking=False) and degrade instead of asserting the lock.","Make sure the lock has a timeout so a crashed owner's lock auto-expires."],"exampleFix":"// before\nasync with lock:  # raises LockError if not acquired in time\n    ...\n// after\nif await lock.acquire(blocking=False):\n    try:\n        ...\n    finally:\n        await lock.release()\nelse:\n    # fall back / skip\n    ...","handlingStrategy":"try-catch","validationCode":"async def acquire_or_fallback(lock):\n    if await lock.acquire(blocking=False):\n        return True\n    # non-blocking failure -> degrade instead of raising in async with\n    return False","typeGuard":"def lock_has_blocking_timeout(lock) -> bool:\n    return lock.blocking and lock.blocking_timeout is not None","tryCatchPattern":"from redis.exceptions import LockError\ntry:\n    async with lock:\n        ...\nexcept LockError as e:\n    if 'Unable to acquire' in str(e):\n        # degrade / skip the critical section\n        ...","preventionTips":["Use acquire(blocking=False) when the lock is optional.","Size blocking_timeout to expected contention.","Keep critical sections short; always release.","Set a lock timeout so crashed owners auto-expire."],"tags":["lock","contention","timeout","asyncio"],"analyzedSha":"da03cdc7e8731092b13e395605c3c1fb2de25de1","analyzedAt":"2026-08-04T20:26:47.563Z","schemaVersion":2}