Laravel storage public url after storage:link not working

Stefan Bogdanescu

Founder & Senior Architect · 2026-06-29

Laravel Company
# Laravel Storage Public URL After `storage:link` Fails: Debugging the 404 Mystery As a senior developer working with the Laravel ecosystem, I’ve seen countless developers run into frustrating issues when trying to expose files stored in the `storage` directory publicly. The scenario you’ve described—where `php artisan storage:link` is executed, but accessing the resulting URL yields a 404 error—is an extremely common point of confusion. This post will dive deep into why this happens, analyze your configuration, and provide the definitive solution for correctly serving public files from your Laravel application. ## Understanding the Storage Link Mechanism The core concept behind making stored files accessible via a URL in Laravel relies entirely on symbolic links (symlinks). When you use the `storage` disk driver, Laravel is designed to read files from the configured location and provide a clean, public-facing path. When you run `php artisan storage:link`, Laravel creates a symbolic link in your `public` directory that points to the actual storage location (`storage/app/public`). This allows web requests hitting `/storage/...` to be mapped to the actual file system paths. Your setup in `filesystems.php` correctly defines this relationship: ```php 'links' => [ public_path('storage') => storage_path('app/public'), ], ``` This configuration tells Laravel: "When a request comes for anything under the `/storage` path, look inside `storage/app/public`." ## Diagnosing the 404 Error If the setup looks correct, why are you getting a 404? There are usually three primary culprits when this happens: 1. **The Symlink Issue:** The most common culprit is that the symbolic link itself was not created correctly, or file permissions prevented the web server (Apache/Nginx) from reading the link. 2. **Path Misinterpretation:** You might be attempting to access the file using a path structure that doesn't align with how the `storage:link` command maps the root. For instance, trying to use the application root (`public`) instead of the Laravel storage mapping. 3. **Disk Configuration Conflict:** While less likely in this specific case, conflicts within your filesystem definitions can sometimes interfere with the link resolution process. In your specific example, accessing `http://localhost:8000/storage/post/1/myimage.png` should theoretically work if everything is configured correctly. The 404 suggests that the web server cannot resolve the path to the physical file, implying the symlink mapping is broken or incomplete for that specific request context. ## The Correct Implementation and Best Practices To ensure reliable public access, we need to confirm the entire chain—from storage setup to web server configuration—is sound. Following Laravel best practices, as detailed by resources like [laravelcompany.com](https://laravelcompany.com), is crucial for robust file handling. ### Step 1: Verify the Link Creation (Crucial) First, ensure you run the command again and check the output for any errors. This step explicitly creates the necessary public interface: ```bash php artisan storage:link ``` After running this, verify that the symbolic link actually exists in your `public` directory pointing to `storage/app/public`. ### Step 2: File System Permissions (The Silent Killer) Often, file system permissions are the invisible barrier. The web server user (e.g., `www-data` or `apache`) must have read access not only to the files in `storage/app/public`, but also to the symbolic link itself. Ensure your storage directory and its contents have appropriate Read/Write/Execute permissions for the web server process. ### Step 3: Accessing the Files Correctly The correct URL structure, based on your configuration, should always start with the publicly exposed link prefix defined in `filesystems.php`, which is `/storage`. **Correct URL Format:** `http://your-app-url/storage/post/1/myimage.png` If you are still encountering issues, it often points to a server configuration problem (e.g., Nginx or Apache not correctly mapping requests to the Laravel public directory) rather than an issue within the PHP code itself. Always ensure your web server is configured to serve files directly from the `public` folder of your application root. ## Conclusion The failure you experienced is rarely due to a flaw in the `filesystems.php` setup itself, but rather a breakdown in the execution or visibility of the symbolic link created by `storage:link`. By strictly following the creation command and carefully checking file system permissions, you can resolve this common roadblock. Remember, leveraging Laravel's built-in filesystem abstraction makes managing public assets straightforward once these foundational steps are correctly implemented. Happy coding!