laravel/framework · error · BadMethodCallException

This cache store does not support locks.

Error message

This cache store does not support locks.

What it means

MemoizedStore::lock() throws BadMethodCallException when the wrapped repository's underlying store is not an instance of LockProvider. The memoized store delegates lock acquisition but cannot fabricate locking on a store (e.g. NullStore, file without locks) that has no lock provider.

Source

Thrown at src/Illuminate/Cache/MemoizedStore.php:176

        unset($this->cache[$this->prefix($key)]);

        return $this->repository->forever($key, $value);
    }

    /**
     * Get a lock instance.
     *
     * @param  string  $name
     * @param  int  $seconds
     * @param  string|null  $owner
     * @return \Illuminate\Contracts\Cache\Lock
     *
     * @throws \BadMethodCallException
     */
    public function lock($name, $seconds = 0, $owner = null)
    {
        if (! $this->repository->getStore() instanceof LockProvider) {
            throw new BadMethodCallException('This cache store does not support locks.');
        }

        return $this->repository->getStore()->lock(...func_get_args());
    }

    /**
     * Restore a lock instance using the owner identifier.
     *
     * @param  string  $name
     * @param  string  $owner
     * @return \Illuminate\Contracts\Cache\Lock
     *
     * @throws \BadMethodCallException
     */
    public function restoreLock($name, $owner)
    {
        if (! $this->repository->getStore() instanceof LockProvider) {
            throw new BadMethodCallException('This cache store does not support locks.');

View on GitHub (pinned to bd6b5437e6)

Solutions

  1. Switch the cache driver to one that implements LockProvider (redis, database, array, memcached, dynamodb).
  2. If you need locks, do not back the memoized store with NullStore or a non-LockProvider custom store.
  3. Implement LockProvider on your custom store class so lock()/restoreLock() are available.

Example fix

// before
// CACHE_STORE=null
Cache::memo()->lock('orders')->block(5); // throws

// after
// CACHE_STORE=redis
Cache::memo()->lock('orders')->block(5);
// or implement LockProvider on your custom store
Defensive patterns

Strategy: type-guard

Validate before calling

$store = Cache::memo()->getStore();
$backing = $store instanceof \Illuminate\Cache\MemoizedStore ? $store->getRepository()->getStore() : $store;
if (! $backing instanceof \Illuminate\Contracts\Cache\LockProvider) {
    throw new \RuntimeException('Backing cache store does not support locks; switch driver.');
}
$store->lock('x');

Type guard

function memoStoreSupportsLocks(\Illuminate\Cache\MemoizedStore $store): bool
{
    return $store->getRepository()->getStore() instanceof \Illuminate\Contracts\Cache\LockProvider;
}

Try / catch

try {
    Cache::memo()->lock('x')->block(5);
} catch (\BadMethodCallException $e) {
    if (str_contains($e->getMessage(), 'does not support locks')) {
        Cache::store('redis')->lock('x')->block(5);
    } else {
        throw $e;
    }
}

Prevention

When it happens

Trigger: Calling Cache::memo()->lock('x') (or resolving a memoized store) when the backing store's driver is null/file/dynamodb configured in a way that the store object is not a LockProvider. Also reached when the default cache driver is such a store.

Common situations: Setting CACHE_STORE=null or CACHE_STORE=file in tests and then exercising code that requests locks via the memoized cache. Wrapping a custom store that omits the LockProvider interface.

Related errors


AI-assisted analysis of laravel/framework@bd6b5437e6 (2026-08-06). Data as JSON: /data/errors/75c936a1a7cba417.json. Report an issue: GitHub.