Laravel Storage Symlink The “public/storage” directory does not exist – One Command Fix
You upload a file, access public/storage/..., and instead of working, Laravel throws this error: The “public/storage” directory does not exist. This simply means the symbolic link between storage/app/public and public/storage is missing or broken. Luckily, it takes a single command to fix it.
1. The one-command fix
Run this inside your project root:
php artisan storage:link
This creates a symlink:
public/storage → storage/app/public
After this, anything stored in storage/app/public becomes accessible at:
https://yourdomain.com/storage/filename.png
If the command succeeds, you’re done.
2. If storage:link fails or returns “File exists”
Case A: The link exists but is broken
Delete the existing folder or symlink:
rm -rf public/storage
php artisan storage:link
This repairs the link and makes uploaded files accessible again.
3. Make sure your files are stored correctly
Laravel only exposes files stored in the public disk.
Your code should write to this disk:
$request->file('image')->store('products', 'public');
This will save to:
storage/app/public/products
And accessible at:
/storage/products/filename.jpg
If you store files in storage/app or storage/app/private, they will not show publicly.
4. Fix permissions (Linux servers)
Sometimes the symlink is correct, but the system cannot read files.
Make sure storage and bootstrap/cache are writable:
chmod -R 775 storage bootstrap/cache
If your server user is different:
chown -R www-data:www-data storage bootstrap/cache
Replace www-data with your web server user (e.g. apache, nginx, www).
5. Fix shared hosting (cPanel, DirectAdmin, Plesk)
On shared hosting, PHP might not have permission to create symlinks.
Instead of php artisan storage:link, use a real directory symlink through File Manager:
- Go to
public_html - Create a symlink/folder shortcut pointing to
/home/username/project/storage/app/public - Name it storage
If your host blocks symlinks, you may need a static copy:
public/storage ← copy files from storage/app/public
(not ideal, but works when access is restricted)
6. Use custom storage paths
If you want custom folder paths, update config/filesystems.php:
'public' => [
'driver' => 'local',
'root' => storage_path('app/public/uploads'),
'url' => env('APP_URL').'/storage/uploads',
'visibility' => 'public',
],
Then re-link:
php artisan storage:link
Quick checklist
- Use the official fix:
php artisan storage:link - Store files in
storage/app/public - Access files via
/storage/... - Fix broken symlink: delete
public/storagethen relink - Ensure writable permissions for
storageandbootstrap/cache - For shared hosting, create the link through cPanel if command is blocked
Once the symlink is working, Laravel will serve your stored files normally without errors.