laravel/framework · error · BadMethodCallException

This cache store does not support locks.

Error message

This cache store does not support locks.

What it means

Thrown by Repository::funnel() when the underlying cache store does not implement Illuminate\Contracts\Cache\LockProvider. Funneling requires distributed locks, so stores like 'array', 'file' (depending on version), 'dynamodb', or custom stores that omit LockProvider cannot back it.

Solutions

  1. Switch CACHE_STORE to a LockProvider-backed store: redis, memcached, database, or dynamodb where supported.
  2. In tests, use a store that supports locks (e.g. database/sqlite with the lock schema) rather than 'array'.
  3. If you must support non-lock stores, branch on $cache->getStore() instanceof LockProvider before calling funnel().

Example fix

// before (tests/.env or phpunit.xml)
CACHE_STORE=array
// after
CACHE_STORE=database
Defensive patterns

Strategy: type-guard

Validate before calling

if (Cache::getStore() instanceof \Illuminate\Contracts\Cache\LockProvider) {
    Cache::funnel('job')->limit(1)->block(5)->then(fn () => doWork());
} else {
    // fallback: run without funneling
    doWork();
}

Type guard

function storeSupportsLocks(\Illuminate\Contracts\Cache\Store $store): bool {
    return $store instanceof \Illuminate\Contracts\Cache\LockProvider;
}

Try / catch

try {
    Cache::funnel('name')->limit(1)->then($callback);
} catch (\BadMethodCallException $e) {
    // store lacks locks; degrade gracefully
    $callback();
}

Prevention

When it happens

Trigger: Calling Cache::funnel('name')->limit(...) while the configured CACHE_STORE is one without lock support (commonly 'array' in tests, or 'file').

Common situations: Running queue/concurrency-limited code in the testing environment with CACHE_STORE=array; deploying to a host where redis/memcached/database is not configured; misconfigured CACHE_DRIVER.

Related errors


AI-assisted analysis of laravel/framework@e0f6eb3518 (2026-08-11). Data as JSON: /api/errors/04e9c28e7147d10f. Report an issue: GitHub.

Appendix: source

Thrown at src/Illuminate/Cache/Repository.php:742

     * @return TReturn
     *
     * @throws \Illuminate\Contracts\Cache\LockTimeoutException
     */
    public function withoutOverlapping($key, callable $callback, $lockFor = 0, $waitFor = 10, $owner = null)
    {
        return $this->store->lock(enum_value($key), $lockFor, $owner)->block($waitFor, $callback);
    }

    /**
     * Funnel a callback for a maximum number of simultaneous executions.
     *
     * @param  \UnitEnum|string  $name
     * @return \Illuminate\Cache\Limiters\ConcurrencyLimiterBuilder
     */
    public function funnel($name)
    {
        if (! $this->store instanceof LockProvider) {
            throw new BadMethodCallException('This cache store does not support locks.');
        }

        return new ConcurrencyLimiterBuilder($this, enum_value($name));
    }

    /**
     * Remove an item from the cache.
     *
     * @param  \UnitEnum|array|string  $key
     * @return bool
     */
    public function forget($key)
    {
        $key = enum_value($key);

        $this->event(new ForgettingKey($this->getName(), $key));

        return tap($this->store->forget($this->itemKey($key)), function ($result) use ($key) {

View on GitHub (pinned to e0f6eb3518)