Fix “nginx error.log Permission Denied” When Recreating Log Files: Complete Troubleshooting Guide


3 views

When you manually recreate Nginx log files, the most common pitfall is overlooking the correct ownership and permissions. The key difference between your manual creation and Nginx's automatic handling lies in these critical aspects:

# This is what proper permissions should look like
$ ls -la /var/log/nginx/
-rw-r----- 1 www-data adm  0 Jan 17 09:00 access.log
-rw-r----- 1 www-data adm  0 Jan 17 09:00 error.log

The two errors you're seeing actually reveal two distinct issues that need addressing:

  1. Log file permissions (error.log access)
  2. PID file creation (/var/run/nginx.pid)
# Comprehensive fix for both issues
sudo chown www-data:adm /var/log/nginx/error.log
sudo chmod 640 /var/log/nginx/error.log
sudo mkdir -p /var/run/nginx
sudo chown www-data:www-data /var/run/nginx

Instead of manually creating files, use these Nginx-native approaches:

# Method 1: Using truncate
sudo -u www-data truncate -s 0 /var/log/nginx/error.log

# Method 2: Using Nginx's log rotation
sudo nginx -s reopen

If the basic fixes don't work, check these deeper system configurations:

# Verify AppArmor/SELinux contexts
ls -Z /var/log/nginx/

# Check parent directory permissions
namei -l /var/log/nginx/error.log

# Alternative startup method for testing
sudo -u www-data nginx -c /etc/nginx/nginx.conf

Add these to your Nginx configuration for more robust logging:

# In nginx.conf
pid /var/run/nginx/nginx.pid;
error_log /var/log/nginx/error.log warn;

# Create systemd override
sudo mkdir -p /etc/systemd/system/nginx.service.d
echo -e "[Service]\nExecStartPost=/bin/chown www-data:adm /var/log/nginx/*.log" | sudo tee /etc/systemd/system/nginx.service.d/log-perms.conf

When you manually delete and recreate Nginx log files, you might encounter permission issues preventing the service from starting. This typically happens because:

  • The new file lacks proper ownership (nginx user/group)
  • Parent directory permissions are restrictive
  • SELinux/AppArmor contexts are missing (on security-enhanced systems)

Instead of using nano, use these commands to properly recreate the log:

sudo rm /var/log/nginx/error.log
sudo touch /var/log/nginx/error.log
sudo chown nginx:nginx /var/log/nginx/error.log
sudo chmod 640 /var/log/nginx/error.log

For a complete solution addressing both log and PID file issues:

# Fix log directory permissions
sudo chown -R nginx:nginx /var/log/nginx
sudo chmod -R 755 /var/log/nginx

# Fix PID directory
sudo mkdir -p /var/run/nginx
sudo chown -R nginx:nginx /var/run/nginx

On RHEL/CentOS systems:

sudo restorecon -Rv /var/log/nginx/
sudo restorecon -Rv /var/run/nginx/

After applying fixes, verify with:

sudo nginx -t  # Test configuration
ls -lZ /var/log/nginx/  # Check SELinux contexts
sudo systemctl start nginx
journalctl -xe  # Check for remaining errors

For future maintenance:

  • Use sudo truncate -s 0 /var/log/nginx/error.log instead of deletion
  • Implement log rotation via /etc/logrotate.d/nginx
  • Consider using sudo systemctl restart nginx which handles log file creation

If problems persist, check:

# Check running user in nginx.conf
grep 'user' /etc/nginx/nginx.conf

# Verify process capabilities
getcap /usr/sbin/nginx

# Check audit logs for SELinux/AppArmor denials
sudo ausearch -m avc -ts recent
sudo dmesg | grep nginx