# Fix Nginx Log Rotation Permission Denied After Logrotate
Your Nginx logs stop rotating, or worse, after logrotate runs, Nginx cannot write to the new log file. You find errors like these:
error: error renaming /var/log/nginx/access.log to /var/log/nginx/access.log.1: Permission denied2026/04/08 08:00:01 [alert] 1234#1234: open() "/var/log/nginx/access.log" failed (13: Permission denied)The new log files are owned by root:root, but the Nginx worker process runs as www-data and cannot write to them.
The Root Cause
Logrotate creates new files with ownership determined by the create directive in the logrotate configuration. If the directive specifies root:root or is missing entirely, the new files are not writable by the Nginx worker process.
Fixing the Logrotate Configuration
Edit /etc/logrotate.d/nginx:
/var/log/nginx/*.log {
daily
missingok
rotate 14
compress
delaycompress
notifempty
create 0640 www-data adm
sharedscripts
prerotate
if [ -d /etc/logrotate.d/httpd-prerotate ]; then \
run-parts /etc/logrotate.d/httpd-prerotate; \
fi \
endscript
postrotate
invoke-rc.d nginx rotate >/dev/null 2>&1
endscript
}The critical line is:
create 0640 www-data admThis creates new log files with permission 0640 (owner read/write, group read), owned by www-data (the user Nginx workers run as), group adm (allows log analysis tools to read).
Verifying Nginx Worker User
Confirm which user your Nginx worker processes run as:
grep "^user" /etc/nginx/nginx.conf
# Default on Debian/Ubuntu: user www-data;
# Default on RHEL/CentOS: user nginx;Adjust the logrotate create directive to match.
Manual Test of Log Rotation
After fixing the configuration, test it:
sudo logrotate -f /etc/logrotate.d/nginx
ls -la /var/log/nginx/You should see:
-rw-r----- 1 www-data adm 0 Apr 8 10:00 access.log
-rw-r----- 1 www-data adm 0 Apr 8 10:00 error.log
-rw-r----- 1 www-data adm 54321 Apr 8 09:59 access.log.1Then verify Nginx can still write:
curl -s http://localhost/ > /dev/null
tail -1 /var/log/nginx/access.logFixing Existing Permissions
If current log files already have wrong ownership, fix them:
sudo chown www-data:adm /var/log/nginx/*.log
sudo chmod 0640 /var/log/nginx/*.logAlternative: Using copytruncate
If the postrotate script fails to signal Nginx properly, use copytruncate:
/var/log/nginx/*.log {
daily
copytruncate
rotate 14
compress
delaycompress
notifempty
}This copies the log file and then truncates the original, so Nginx never needs to reopen a new file. However, there is a small window where log entries can be lost between the copy and the truncate. For production systems, the create + postrotate approach is preferred.
Systemd Journal Integration
On modern systems, consider sending Nginx logs to journald instead of files:
error_log stderr error;
access_log /dev/stdout;Then use journalctl for log management, which handles rotation automatically:
journalctl -u nginx --since "1 hour ago"
journalctl -u nginx --vacuum-size=100MThis eliminates logrotate permission issues entirely, though it requires adapting your log analysis pipeline.