redis/redis-py · error · LockNotOwnedError
Cannot reacquire a lock that's no longer owned
Error message
Cannot reacquire a lock that's no longer owned
What it means
do_reacquire runs the Lua reacquire script; if the key is gone/TTL-expired or the token differs, it returns 0 and LockNotOwnedError is raised. The lock expired before the reacquire request reached the server, so the TTL could not be reset.
Solutions
- Reacquire before expiry with margin.
- Catch LockNotOwnedError and re-acquire the lock fresh.
- Use a longer base timeout to give renewal more room.
Defensive patterns
Strategy: try-catch
Try / catch
from redis.exceptions import LockNotOwnedError
try:
await lock.reacquire()
except LockNotOwnedError:
# lock expired before reacquire: re-acquire fresh
await lock.acquire() Prevention
- Reacquire before expiry with margin.
- Catch LockNotOwnedError and re-acquire rather than assuming success.
- Use a longer base timeout when renewal timing is uncertain.
When it happens
Trigger: Calling reacquire() after the lock TTL already expired; another holder took over the key between the last operation and reacquire.
Common situations: Renewal scheduled too late; long event-loop/GC pause pushing reacquire past expiry.
Related errors
- Cannot extend a lock that's no longer owned
- Cannot release a lock that's no longer owned
- Cannot extend an unlocked lock
- Cannot reacquire an unlocked lock
- Cannot release a lock that's not owned or is already…
AI-assisted analysis of redis/redis-py@6a6b581b48 (2026-08-10).
Data as JSON: /api/errors/c5d47d88e0776d55.
Report an issue: GitHub.
Appendix: source
Thrown at redis/asyncio/lock.py:344
def reacquire(self) -> Awaitable[Literal[True]]:
"""
Resets a TTL of an already acquired lock back to a timeout value.
"""
if self.local.token is None:
raise LockError("Cannot reacquire an unlocked lock")
if self.timeout is None:
raise LockError("Cannot reacquire a lock with no timeout")
return self.do_reacquire()
async def do_reacquire(self) -> Literal[True]:
timeout = int(self.timeout * 1000)
if not bool(
await self.lua_reacquire(
keys=[self.name], args=[self.local.token, timeout], client=self.redis
)
):
raise LockNotOwnedError("Cannot reacquire a lock that's no longer owned")
return True
View on GitHub (pinned to 6a6b581b48)