Laravel缓存目录权限异常:file_put_contents权限拒绝问题排查
It sounds like you're hitting a common permission edge case where overwriting existing cache keys works, but creating new ones fails—this usually boils down to missing directory permissions, incorrect umask settings, or the cron user not having proper group access. Let's walk through the complete, correct permission setup for Laravel's cache (and storage) directories:
1. Reset Full Ownership & Permissions
First, ensure both the storage and bootstrap/cache directories (Laravel uses both for caching operations) are properly owned by the web server user/group, and set up with the right permissions:
Run these commands from your Laravel root directory:
# Set ownership to www-data (matches your Nginx user/group) sudo chown -R www-data:www-data storage bootstrap/cache # Set base permissions to 775 (read/write/execute for owner/group, read/execute for others) sudo chmod -R 775 storage bootstrap/cache # Add the setgid bit to directories so new files inherit the www-data group sudo find storage bootstrap/cache -type d -exec chmod g+s {} \;
The g+s bit is crucial here—it ensures any new subdirectories or files created in these folders inherit the parent directory's group (www-data), preventing permission conflicts between different processes (like your cron job and the web server).
2. Configure Laravel's Umask
Laravel's default umask can create files with restrictive permissions (644, which blocks group write access). To fix this, update your bootstrap/app.php file to set a umask that allows group write access:
Add this line immediately after the $app instance is created:
$app = Illuminate\Foundation\Application::configure(basePath: dirname(__DIR__)) ->withRouting( web: __DIR__.'/../routes/web.php', commands: __DIR__.'/../routes/console.php', health: '/up', ) ->withMiddleware(function (Illuminate\Foundation\Http\Middleware\Middleware $middleware) { // ... your existing middleware config }) ->withExceptions(function (Illuminate\Foundation\Exceptions\Handler $handler) { // ... your existing exception config }) ->useUmask(0002); // Add this line!
Setting the umask to 0002 ensures new files are created with 664 permissions (owner/group can read/write) and new directories with 775, which aligns perfectly with our earlier permission setup.
3. Verify Cron User Group Access
If your scheduled task runs under a different user (e.g., your system user <user>) instead of www-data, that user needs to be in the www-data group to write to the cache directories:
sudo usermod -aG www-data <user>
Log out and back in (or restart your cron service) for the group change to take effect. This is a common oversight—cron jobs often run as the user who created them, not the web server user.
4. Confirm Cache Driver Configuration
Double-check your .env file to ensure you're using the file cache driver (since your error is file-system related):
CACHE_DRIVER=file
If you're using a different driver (like Redis or Memcached), this fix won't apply—but based on your error message, the file driver is what you're using.
5. Test the Fix
Manually create a new cache key to verify everything works:
# Run Laravel Tinker php artisan tinker # Create a new cache key Cache::put('test_new_key', 'success', 60);
If this runs without errors, your scheduled task should now be able to create new cache keys without permission issues.
Why Your Previous Setup Failed
You had the right ownership and base permissions, but were missing two critical pieces:
- The
g+sbit to ensure new directories inherit thewww-datagroup. - The umask setting to make new files group-writable.
- (Possibly) your cron user not being in the
www-datagroup, blocking write access.
内容的提问来源于stack exchange,提问作者Thierry Maasdam




