laravel/framework · error · InvalidArgumentException
The [{$disk}] disk conflicts with the [{$served[$uri]}] disk
Error message
The [{$disk}] disk conflicts with the [{$served[$uri]}] disk at [{$uri}]. Each served disk must have a unique URL. What it means
Thrown by FilesystemServiceProvider::serveFiles() during boot when two local disks both enable 'serve' => true and would be served from the same URI (default '/storage', or a shared 'url' path). Laravel registers a route per served disk, so each disk must occupy a unique URL prefix; a collision would silently shadow one disk's files behind another's route.
Source
Thrown at src/Illuminate/Filesystem/FilesystemServiceProvider.php:102
{
if ($this->app instanceof CachesRoutes && $this->app->routesAreCached()) {
return;
}
$served = [];
foreach ($this->app['config']['filesystems.disks'] ?? [] as $disk => $config) {
if (! $this->shouldServeFiles($config)) {
continue;
}
$this->app->booted(function ($app) use ($disk, $config, &$served) {
$uri = isset($config['url'])
? rtrim(parse_url($config['url'])['path'], '/')
: '/storage';
if (isset($served[$uri])) {
throw new InvalidArgumentException(
"The [{$disk}] disk conflicts with the [{$served[$uri]}] disk at [{$uri}]. Each served disk must have a unique URL."
);
}
$served[$uri] = $disk;
$isProduction = $app->isProduction();
Route::get($uri.'/{path}', function (Request $request, string $path) use ($disk, $config, $isProduction) {
return (new ServeFile(
$disk,
$config,
$isProduction
))($request, $path);
})->where('path', '.*')->name('storage.'.$disk);
Route::put($uri.'/{path}', function (Request $request, string $path) use ($disk, $config, $isProduction) {
return (new ReceiveFile(View on GitHub (pinned to bd6b5437e6)
Solutions
- Give each served local disk a unique 'url' key, e.g. '/storage' and '/exports'.
- Disable 'serve' on disks that don't need direct serving.
- Ensure the 'url' config resolves to distinct path components (parse_url path).
- Re-run `php artisan route:cache` (or clear it) after fixing config.
Example fix
// before - two served disks collide at /storage
// 'public' => ['driver' => 'local', 'root' => storage_path('app/public'), 'serve' => true],
// 'private' => ['driver' => 'local', 'root' => storage_path('app/private'), 'serve' => true],
// after - distinct urls
// 'public' => ['driver' => 'local', 'root' => storage_path('app/public'), 'serve' => true, 'url' => '/storage'],
// 'private' => ['driver' => 'local', 'root' => storage_path('app/private'), 'serve' => true, 'url' => '/files'], Defensive patterns
Strategy: validation
Validate before calling
// Validate that all served local disks have unique URIs at boot
$served = [];
foreach (config('filesystems.disks', []) as $name => $cfg) {
if (($cfg['driver'] ?? '') !== 'local' || empty($cfg['serve'])) continue;
$uri = isset($cfg['url']) ? rtrim((string) parse_url($cfg['url'], PHP_URL_PATH), '/') : '/storage';
if (isset($served[$uri])) {
throw new RuntimeException("Disk {$name} collides with {$served[$uri]} at {$uri}");
}
$served[$uri] = $name;
} Type guard
function servedUrisAreUnique(): bool
{
$uris = [];
foreach (config('filesystems.disks', []) as $cfg) {
if (($cfg['driver'] ?? '') !== 'local' || empty($cfg['serve'])) continue;
$uri = isset($cfg['url']) ? rtrim((string) parse_url($cfg['url'], PHP_URL_PATH), '/') : '/storage';
if (in_array($uri, $uris, true)) return false;
$uris[] = $uri;
}
return true;
} Try / catch
// This fires during boot(); wrap config validation in a boot-time check
// and surface a clear 500 before routes register.
if (! servedUrisAreUnique()) {
throw new \InvalidArgumentException('Two served local disks share a URL prefix');
} Prevention
- Give each served local disk a unique 'url'.
- Only enable 'serve' => true on disks that need direct serving.
- Add a boot-time config validator in a service provider.
When it happens
Trigger: Having two entries in filesystems.disks with 'driver' => 'local' and 'serve' => true that both resolve to the same URI (both default to /storage, or both share the same configured 'url' path).
Common situations: Enabling file serving on multiple local disks (e.g. a public and a private-with-prefix disk) without giving each a distinct 'url'; copying a disk config block and forgetting to change the url path.
Related errors
- Database file at path [{$path}] does not exist. Ensure this
- This driver does not support retrieving URLs.
- Unknown visibility: {$visibility}.
- Disk [{$name}] does not have a configured driver.
- Driver [{$driver}] is not supported.
AI-assisted analysis of laravel/framework@bd6b5437e6 (2026-08-06).
Data as JSON: /data/errors/d01ffced9b4722b4.json.
Report an issue: GitHub.