How to Resolve file_put_contents failed to open stream Permission denied Error【Laravel】
Table Of Contents
How to fix Laravel's file_put_contents(storage/framework/views/...): Failed to open stream: Permission denied. chmod -R 777 worked for me, and in November 2026 I confirmed on Laravel 13 that matching the owner to the PHP user also fixes it, and that newer versions show a tempnam() error instead.
Error Message
file_put_contents(/var/www/html/laravel-docker/src/storage/framework/views/b560c9abc12f714c866236b477e2d6a6.php): Failed to open stream: Permission denied
Solution (What Actually Fixed It for Me)
Grant permissions to the storage directory to resolve this issue.
chmod -R 777 storageAt the time, this made the page display again.
However, 777 lets anyone read, write, and execute the files, so I no longer recommend it on a production server.
See "What I Confirmed on Laravel 13 in November 2026" below for a fix that changes the owner to the user running PHP instead.
Explanation of the Solution
This error occurs because the system does not have permission to read and write files under the storage directory. By granting the necessary permissions to the storage directory, the issue can be resolved.
chmod -R 777 storageHere, "the system" means the user that runs PHP (the web server or PHP-FPM user). The error happens when the files were created by a different user (such as root) than the one running PHP.
What I Confirmed on Laravel 13 in November 2026
In November 2026, I reproduced and fixed the error with Docker's php:8.4-cli image (PHP 8.4.27) and Laravel 13.40.0. With the project owned by root (755) and php artisan serve running as www-data, the top page returned a 500 error. (The database directory was made writable for www-data, because the default session driver uses SQLite.)
Newer Laravel Shows a tempnam() Error Instead
The error shown was not file_put_contents but:
tempnam(): file created in the system's temporary directoryThe stack trace showed it failed while writing a compiled Blade view to storage/framework/views. Laravel 11.30.0 and 12.0.0 write compiled views with $this->files->put() (file_put_contents()) (BladeCompiler.php in v11.30.0), while 12.71.0 and 13.40.0 use $this->files->replace(), which creates a temporary file with tempnam() first (BladeCompiler.php in v13.40.0).
With SESSION_DRIVER=file and views precompiled by php artisan view:cache, Laravel 13 still showed the file_put_contents error, this time for the sessions directory:
file_put_contents(/var/www/app/storage/framework/sessions/bgfkZCrkYwGHWjnZhUCZuLDM2RtznaVrB1b2tQQf): Failed to open stream: Permission deniedIf storage/logs/laravel.log cannot be written, the error was:
The stream or file "/var/www/app/storage/logs/laravel.log" could not be opened in append mode: Failed to open stream: Permission deniedThe path in the message tells you which directory lacks permission.
Both chmod -R 777 and Changing the Owner Fix It
Running the original chmod -R 777 storage returned the page with 200. After resetting to root/755, changing the owner to the PHP user also returned 200:
chown -R www-data:www-data storage bootstrap/cache
chmod -R 775 storage bootstrap/cacheRunning an artisan command as root afterwards created laravel.log owned by root (644), and the error came back when www-data tried to log. chown www-data:www-data storage/logs/laravel.log fixed it again. If the error returns, check ls -l for root-owned files inside storage.
On macOS Docker Desktop, a Laravel project inside a mounted Mac folder did not reproduce the error: files showed root as the owner, but www-data could still write to them (the mount type was fakeowner). The checks above were done in a directory inside the container.
Reference: Directory Permissions in the Official Docs
According to the Laravel 13.x documentation, Laravel needs to write to bootstrap/cache and storage, so the web server process owner should have permission to write to them. Source: Deployment - Laravel 13.x
The actual user name depends on your server setup, so check which user runs PHP before running chown.
Further Details
What is storage?
When you install a Laravel project, the following directory structure is created:
├── app
│ ├── Console
│ ├── Exceptions
│ ├── Http
│ │ ├── Controllers
│ │ ├── Middleware
│ ├── Models
│ ├── Providers
├── bootstrap
│ ├── cache
├── config
├── database
│ ├── factories
│ ├── migrations
│ ├── seeders
├── public
│ ├── index.php
├── resources
├── routes
├── storage ← this one
│ ├── app
│ ├── framework
│ │ ├── cache
│ │ ├── sessions
│ │ ├── testing
│ │ └── views
│ ├── logs
├── tests
├── vendor
├── .env
├── .env.example
...etc.Inside this structure, there is a storage directory. This directory serves several functions, such as:
- Outputting logs
- Storing various cache data
- Loading cached data
These roles contribute to rendering the display on the screen, and without proper permissions, the error mentioned earlier will occur.
Be Careful with the Directory Path
A common mistake is to misidentify the directory path. As mentioned, you must grant permissions to the storage directory, so be cautious with specifying the relative path.
chmod -R 777 relative/pathIf needed, change directories to the Laravel project folder before running the chmod command:
cd laravel-projectI hope this information is helpful to someone.




