Fix laravel.log could not be opened Error on New Server Without Using 777
You set up a fresh Laravel project on a new server, open the site, and boom: UnexpectedValueException: The stream or file “/var/www/project/storage/logs/laravel.log” could not be opened Most tutorials tell you to run chmod -R 777 storage, which “works” but is a bad idea for security. The good news is you can fix this cleanly without ever using 777.
Let’s walk through what this error means and how to solve it properly.
What this error actually means
Laravel writes logs to:
storage/logs/laravel.log
The error appears when the web server user (for example www-data, nginx, apache, www) cannot:
- Create the
laravel.logfile, or - Write into the
storage/logsdirectory.
Common reasons:
- Files were uploaded by a different user (like
rootor your SSH user). - Directories have restrictive permissions or wrong owners.
- On some systems, SELinux or similar security layers block writes.
We fix this by:
- Giving the web server user ownership of the right folders.
- Using safe permissions like 755 for directories and 644 for files.
Step 1: Find your web server user
SSH into your server and check which user runs PHP.
For Nginx with PHP-FPM on Ubuntu, it is usually:
www-data(Ubuntu/Debian)nginx(CentOS/Alma/Rocky)apache(some Apache setups)
You can inspect the PHP-FPM pool config, for example:
cat /etc/php/8.3/fpm/pool.d/www.conf | grep "^user"
cat /etc/php/8.3/fpm/pool.d/www.conf | grep "^group"
You should see something like:
user = www-data
group = www-data
Remember this user and group. We will use them in the next commands.
Step 2: Set correct owner for storage and cache
Go to your Laravel project directory:
cd /var/www/project # adjust to your path
Change owner of the folders Laravel needs to write to:
sudo chown -R www-data:www-data storage bootstrap/cache
Replace www-data with the user and group you found in step 1.
This gives the web server ownership of only the necessary directories, not the whole project.
Step 3: Apply safe permissions (no 777)
Now set proper permissions for directories and files.
Directories need execute permission to allow entering them, so 755 is a good default:
sudo find storage -type d -exec chmod 755 {} \;
sudo find bootstrap/cache -type d -exec chmod 755 {} \;
Files only need read and write (for owner), so 644 is fine:
sudo find storage -type f -exec chmod 644 {} \;
sudo find bootstrap/cache -type f -exec chmod 644 {} \;
These settings are much safer than 777 but still allow Laravel to create and write its log files.
Step 4: Make sure the logs directory exists
Sometimes the logs folder or laravel.log file is missing, especially on a brand new project.
Ensure the directory exists:
mkdir -p storage/logs
sudo chown -R www-data:www-data storage/logs
sudo chmod 755 storage/logs
You do not need to manually create laravel.log most of the time. Laravel will create it automatically on the next request as long as the directory is writable.
Step 5: Clear caches and reload services
If you changed users or permissions after deploying, it is good to clear cached configuration and restart PHP-FPM.
From your project root:
php artisan config:clear
php artisan cache:clear
php artisan optimize:clear
Then restart PHP-FPM and your web server:
sudo systemctl restart php8.3-fpm
sudo systemctl restart nginx # or apache2
Reload your site in the browser and the error should be gone.
Step 6: Handling SELinux (CentOS / RHEL / Fedora)
If you are on a system with SELinux enforcing, normal permissions may still look correct while SELinux blocks the write.
You can check for denials with:
sudo ausearch -m avc -ts recent
To allow HTTP processes to write to your Laravel directory:
sudo chcon -R -t httpd_sys_rw_content_t storage bootstrap/cache
This assigns the correct SELinux context to the writable folders.
Step 7: Docker and shared volumes
If you use Docker, the problem can happen because the host user and container user differ.
Inside the PHP container, run:
cd /var/www/project
chown -R www-data:www-data storage bootstrap/cache
find storage -type d -exec chmod 755 {} \;
find storage -type f -exec chmod 644 {} \;
Make sure the container’s web server user (often www-data) owns the volume-mounted folders.
Quick command summary
Here is a compact list of commands you can adapt for your server.
From your Laravel project root:
# Change owner to web server user
sudo chown -R www-data:www-data storage bootstrap/cache
# Directories: 755
sudo find storage bootstrap/cache -type d -exec chmod 755 {} \;
# Files: 644
sudo find storage bootstrap/cache -type f -exec chmod 644 {} \;
# Ensure logs directory exists
mkdir -p storage/logs
sudo chown -R www-data:www-data storage/logs
sudo chmod 755 storage/logs
After running these, reload your site and Laravel should be able to create and write to laravel.log without any need for chmod 777.
Fixing the laravel.log could not be opened error on a new server is really about giving Laravel the right level of access, not full access. With correct owners and sane permissions, your application stays secure and your logs work exactly as they should.