NotWritableException异常排查:本地正常的AWS S3头像上传功能在测试服务器报错
NotWritableException on AWS S3 Avatar Upload (Test Server) Let’s walk through how to diagnose and fix this error—since your code works locally but fails on test, we can rule out basic logic issues and focus on environment-specific quirks.
1. Verify the Actual File Path and Directory Permissions
Even though your code runs File::makeDirectory(), the test server might have hidden permission issues:
- Check the absolute path: Add a temporary debug line right after creating the directory to confirm where the code is trying to write:
Make sure this path exists on the test server, and the web server user (e.g.,// After File::makeDirectory() dd(public_path($folderPath)); // Or storage_path() if you're using storage instead of publicwww-datafor Apache,nginxfor Nginx) has write access to it. - Manual permission check: SSH into the test server and run:
Ensure the directory’s permissions are at leastls -ld /path/to/your/project/uploads/profile_pictures/$USER_ID775, and the owner/group includes the web server user. If the parentuploads/directory has restrictive permissions, recursive creation might not fix it—manually setuploads/to775first.
2. Fix Directory Creation Permissions
The File::makeDirectory() method’s fourth parameter controls whether to apply permissions recursively to all created subdirectories. Update your directory creation line to:
if (!File::exists($folderPath)) { File::makeDirectory($folderPath, 0775, true, true); // Fourth param enforces permissions }
This ensures every nested directory (not just the final one) gets the correct write permissions.
3. Check for SELinux/AppArmor Restrictions
Many Linux servers use SELinux or AppArmor to restrict web server access to files, even if filesystem permissions look correct:
- Test with SELinux disabled: Run
setenforce 0temporarily. If the upload works, SELinux was blocking the write. - Set permanent SELinux rules: To fix this without disabling SELinux, apply the correct context to your uploads directory:
(Replacechcon -R -t httpd_sys_rw_content_t /var/www/your-project/uploads/var/www/your-projectwith your actual project path.)
4. Skip Local Storage (Optimize and Avoid the Issue Altogether)
Since you’re uploading to S3 anyway, you don’t need to save the images locally first—this eliminates the write error entirely and improves efficiency. Modify your code like this:
// Remove these local save lines: // $img->save($fullPath); // $smallImg->save($fullPathSmall); // $mediumImg->save($fullPathMedium); // Directly upload encoded images to S3 Storage::disk('s3')->put($fullPath, $img->encode('png', 90), 'public'); Storage::disk('s3')->put($fullPathSmall, $smallImg->encode('png', 90), 'public'); Storage::disk('s3')->put($fullPathMedium, $mediumImg->encode('png', 90), 'public'); // Update the user's profile image URL to use the S3 URL instead of local path $data = ['profile_image' => Storage::disk('s3')->url($fullPath)];
This way, you bypass local filesystem writes entirely, which removes the root cause of the NotWritableException.
5. Check Disk Space
Don’t overlook the simplest fix: ensure the test server has enough free disk space. Run df -h in SSH to check if any mounted filesystem is full.
内容的提问来源于stack exchange,提问作者Devin Y

