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 abstract base Lock::refresh() throws RuntimeException because not all lock backends support extending a held lock's TTL. Drivers that support it (e.g. RedisLock, PhpRedisLock) override refresh(); drivers that don't (e.g. ArrayLock, DynamoDbLock) inherit the throwing implementation.
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 bd6b5437e6)
Solutions
- Use a refresh-capable driver (redis, database) if your workload relies on extending locks.
- Guard the call: check the concrete class before calling refresh().
- Instead of refresh(), release and re-acquire the lock to extend ownership on drivers without native refresh.
- In tests, mock the lock or use a redis-compatible fake if refresh() must succeed.
Example fix
// before
$lock = Cache::store('array')->lock('orders', 60);
$lock->block(5);
$lock->refresh(60); // throws on array driver
// after (release + re-acquire)
$lock->release();
$lock = Cache::store('array')->lock('orders', 60);
$lock->block(5);
// or switch store to redis/database for refresh support Defensive patterns
Strategy: type-guard
Validate before calling
$lock = Cache::lock('orders', 60);
$reflectable = new \ReflectionMethod($lock, 'refresh');
if ($reflectable->getDeclaringClass()->getName() === \Illuminate\Cache\Lock::class) {
throw new \RuntimeException('This lock driver does not support refresh(); use redis/database.');
}
$lock->refresh(60); 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(60);
} catch (\RuntimeException $e) {
if (str_contains($e->getMessage(), 'does not support refreshing')) {
$lock->release();
$lock = Cache::lock('orders', 60);
$lock->block(5);
} else {
throw $e;
}
} Prevention
- Use redis or database drivers when locks need extending.
- Check the concrete lock class before refresh().
- Prefer release()+re-acquire() over refresh() in driver-agnostic code.
- Document which drivers support refresh() in project notes.
When it happens
Trigger: Acquiring a lock via Cache::lock('x') then calling $lock->refresh(30) when the underlying store is array, file, or another driver whose Lock subclass does not override refresh().
Common situations: Using the array driver in tests and exercising long-running lock code that calls refresh(). Switching a cache driver from redis to array/file and forgetting that refresh() is unsupported. Writing library code that assumes all locks are refreshable.
Related errors
- This cache store does not support locks.
- This cache store does not support flushing locks.
- Flushing locks is only supported when the lock store is sepa
- Driver [{$config['driver']}] is not supported.
- Flushing locks is only supported when the lock store is sepa
AI-assisted analysis of laravel/framework@bd6b5437e6 (2026-08-06).
Data as JSON: /data/errors/691fe2d0a423641e.json.
Report an issue: GitHub.