ErrorException: file_put_contents(/var/www/html/storage/logs/laravel.log): Failed to open stream: Permission denied
ID: php/permission-denied-storage
Version Compatibility
| Version | Status | Introduced | Deprecated | Notes |
|---|---|---|---|---|
| 83 | active | — | — | — |
Root Cause
Permission denied errors on storage directories occur when the PHP process (typically www-data or nginx user) does not have write permissions to the storage/logs, storage/framework/cache, or storage/framework/sessions directories. This is one of the most common deployment issues.
genericWorkarounds
-
94% success Set correct ownership and permissions for the storage and bootstrap/cache directories
Run 'chown -R www-data:www-data storage bootstrap/cache' to set the owner to the web server user. Then 'chmod -R 775 storage bootstrap/cache' to allow group write. Ensure the deploy user is in the www-data group. For Laravel, also run 'php artisan storage:link'.
-
88% success Use ACLs for fine-grained permission control in multi-user deployments
Use POSIX ACLs to grant write access without changing ownership: 'setfacl -R -m u:www-data:rwX storage' and 'setfacl -R -d -m u:www-data:rwX storage'. This allows the deploy user to keep ownership while granting the web server write access. Verify with 'getfacl storage'.
Dead Ends
Common approaches that don't work:
-
Setting chmod 777 recursively on the entire project directory
85% fail
chmod 777 makes all files world-readable, writable, and executable, creating a severe security vulnerability. Any user on the system can read configuration files with database credentials and modify application code. This is a critical security anti-pattern.
-
Running the web server as root to bypass permission checks
92% fail
Running PHP-FPM or Apache as root means any vulnerability in the application gives the attacker full system access. If the application is compromised, the attacker can read/modify any file on the system, install backdoors, or pivot to other services.