laravel/framework · warning · RuntimeException
This lock driver does not support refreshing locks.
Error message
This lock driver does not support refreshing locks.
What it means
The base Lock::refresh is a stub that always throws. Subclasses with refresh support (e.g., RedisLock, DatabaseLock) override this method to extend the TTL atomically. If you call refresh() on a lock instance whose driver does not override it, you hit the base implementation. This signals that the underlying store cannot safely extend a lock without re-acquiring it.
Solutions
- Switch to a driver whose Lock subclass overrides refresh(): RedisLock or DatabaseLock.
- Re-acquire instead of refresh: release() the current lock and acquire() a new one with the desired TTL.
- If authoring a custom Lock, override refresh($seconds = null) to atomically extend the TTL (e.g., via EXPIRE with owner token check).
Example fix
// before
$lock = Cache::lock('process-' . $id, 30);
// long-running work on array driver
$lock->refresh(30); // RuntimeException
// after - re-acquire
$lock->release();
$lock = Cache::block('process-' . $id, 30, function () {
// continue work
});
// OR use a driver that supports refresh:
// CACHE_LOCK_STORE=redis Defensive patterns
Strategy: validation
Validate before calling
// Validate the lock supports refresh before calling
$lock = Cache::lock('job-' . $id, 30);
$reflector = new \ReflectionMethod($lock, 'refresh');
if ($reflector->getDeclaringClass()->getName() === \Illuminate\Cache\Lock::class) {
// base stub would throw; re-acquire instead
$lock->release();
$lock = Cache::lock('job-' . $id, 30);
} else {
$lock->refresh(30);
} Type guard
function lockSupportsRefresh(\Illuminate\Contracts\Cache\Lock $lock): bool
{
return (new \ReflectionMethod($lock, 'refresh'))
->getDeclaringClass()
->getName() !== \Illuminate\Cache\Lock::class;
} Try / catch
try {
$lock->refresh(30);
} catch (\RuntimeException $e) {
if (str_contains($e->getMessage(), 'does not support refreshing locks')) {
// fall back: release and re-acquire
$lock->release();
$lock = Cache::lock($lock->owner() ? 'job-' . $id : 'job-' . $id, 30)->block(5);
} else {
throw $e;
}
} Prevention
- Standardize on RedisLock or DatabaseLock when code calls refresh().
- Add a project helper refreshLock($lock, $ttl) that branches on driver capability.
- When authoring custom Lock subclasses, override refresh() to extend TTL atomically.
- Test lock behavior against the same driver used in production.
When it happens
Trigger: Calling $lock->refresh(60) on a lock acquired from a driver that doesn't support TTL extension (e.g., ArrayLock, or custom Lock subclass without overriding refresh). Also when calling refresh() on a lock restored via restoreLock() that lost its concrete subclass.
Common situations: Code designed for RedisLock deployed against the array driver in tests. Custom lock implementations that subclass Lock but forget to override refresh(). Long-running jobs that try to extend their lock mid-execution on an unsupported driver.
Related errors
- DynamoDb does not support flushing an entire table. Please…
- Flushing locks is only supported when the lock store is…
- Flushing locks is only supported when the lock store is…
- Flushing locks is only supported when the lock store is…
- Flushing locks is only supported when the lock store is…
AI-assisted analysis of laravel/framework@e0f6eb3518 (2026-08-11).
Data as JSON: /api/errors/691fe2d0a423641e.
Report an issue: GitHub.
Appendix: source
Thrown at src/Illuminate/Cache/Lock.php:149
try {
return $callback();
} finally {
$this->release();
}
}
return true;
}
/**
* Attempt to refresh the lock for the given number of seconds.
*
* @param int|null $seconds
* @return bool
*/
public function refresh($seconds = null)
{
throw new RuntimeException('This lock driver does not support refreshing locks.');
}
/**
* Returns the current owner of the lock.
*
* @return string
*/
public function owner()
{
return $this->owner;
}
/**
* Determine if the lock is currently held by any process.
*
* @return bool
*/
public function isLocked(): boolView on GitHub (pinned to e0f6eb3518)