NGINX fails to start primarily due to syntax errors in configuration files, port conflicts, or permission issues. The most effective first step is running
nginx -t to validate the configuration and identify specific line numbers causing the failure. If the config is valid, check system logs and ensure no other process is binding to port 80 or 443.
Immediate Diagnostic Steps
When a service fails to initialize, you need precise error data rather than guessing. The single most important command for NGINX troubleshooting is the configuration test. This utility parses your configuration files without starting the server, catching syntax errors that would otherwise prevent the daemon from launching.
Run the following command in your terminal:
sudo nginx -t
If this command returns an error, it will specify the exact file and line number where the problem lies. Common issues include missing semicolons, unclosed brackets, or typos in directives. Fix these errors, save the file, and run the test again until it reports "syntax is ok".
If
nginx -t succeeds but the service still fails to start, the issue likely lies outside the configuration syntax. In this scenario, proceed to check the system journal for startup failures. Use the following command to view recent log entries related to NGINX:
sudo journalctl -xeu nginx.service
Look for lines indicating "Failed to start" or "Permission denied". These messages provide critical context about whether the process was killed by the operating system's security mechanisms or if it could not bind to the required network ports.
Common Causes and Solutions
There are three primary reasons why NGINX refuses to start after a successful configuration test. Addressing these systematically resolves the majority of startup failures.
1. Port Conflicts
Another application may already be using port 80 (HTTP) or port 443 (HTTPS). NGINX cannot bind to a port that is already in use by another process. To verify this, use the
ss or
netstat command to list processes listening on these ports.
sudo ss -tlnp | grep :80
sudo ss -tlnp | grep :443
If you see another process like Apache or another web server occupying these ports, you must either stop that conflicting service or change your NGINX configuration to listen on different ports. Ensure you do not have duplicate
listen directives pointing to the same address and port combination within your virtual host files.
2. Permission Issues
NGINX runs as a specific user, typically
www-data on Debian/Ubuntu systems or
nginx on RHEL/CentOS. If your configuration references files or directories that this user cannot read, the service will fail. This often happens after moving files manually with root privileges without adjusting ownership.
Check the permissions of your document root and configuration files. You can fix ownership issues by running:
sudo chown -R www-data:www-data /var/www/html
sudo chmod -R 755 /var/www/html
Always ensure that the directory containing your HTML files is readable by the NGINX worker processes. If you are using custom SSL certificates, ensure the private key is readable only by the root user or the NGINX user, depending on your security policy, but never world-readable.
3. SELinux or AppArmor Restrictions
On systems with mandatory access control enabled, such as those using SELinux (common on CentOS/RHEL) or AppArmor (common on Ubuntu), NGINX may be blocked from accessing certain resources. Even if permissions look correct in the traditional Unix sense, the security module might deny access.
For SELinux, check the audit log for denials:
sudo ausearch -m avc -ts recent
If you find denials related to NGINX, you may need to adjust SELinux contexts or boolean settings. For example, allowing NGINX to connect to the network or read specific directories might require commands like:
sudo setsebool -P httpd_can_network_connect 1
Similarly, if you suspect AppArmor is blocking the service, check the syslog for AppArmor denial messages. Disabling the profile temporarily for testing can help isolate whether this is the cause, though re-enabling it with correct rules is the proper long-term solution.
Verifying the Fix
Once you have addressed the identified issue, restart the service to apply changes. Always test the configuration before restarting to avoid leaving the server down.
sudo systemctl restart nginx
sudo systemctl status nginx
The status output should show "active (running)" with a green indicator. If it shows "failed," refer back to the journalctl logs to see if new errors appeared during the restart attempt. This iterative process of testing, fixing, and restarting is the standard workflow for resolving startup issues.
For related infrastructure problems, such as background tasks failing alongside web services, you might also want to review how other daemons handle similar startup constraints. See our guide on
Troubleshooting Cron Service Failures: Why and How to Fix to understand broader service management patterns. Additionally, if your NGINX starts successfully but fails to serve dynamic content correctly, ensure your PHP-FPM isolation is configured properly to avoid security gaps. Check out
PHP-FPM & Nginx: Security Isolation Not Working for details on keeping your stack secure.
Frequently Asked Questions
Why does nginx -t say OK but the service still won't start?
This usually indicates a runtime environment issue rather than a syntax error. Check for port conflicts, permission denials from SELinux/AppArmor, or insufficient disk space preventing the creation of PID files. Review the system journal for detailed error messages that the config test cannot capture.
How do I find which process is using port 80?
Use the command
sudo lsof -i :80 or
sudo ss -tlnp | grep :80 to identify the Process ID and name. Once identified, you can decide whether to stop that process or reconfigure NGINX to use a different port.
Can I run NGINX as root?
While technically possible, it is strongly discouraged for security reasons. Running as root exposes your entire system if NGINX is compromised. Instead, configure NGINX to run as a dedicated unprivileged user and use root privileges only for binding to privileged ports below 1024 via capabilities or systemd features.
What should I do if my configuration files are too large to edit manually?
Break down your configuration into smaller included files using the
include directive. This makes debugging easier because
nginx -t will point to the specific small file causing the error. Keep your main
nginx.conf minimal and manage site-specific configurations separately.
Does upgrading NGINX break existing configurations?
Upgrades generally maintain backward compatibility, but deprecated directives may be removed in major versions. Always run
nginx -t immediately after upgrading to catch any warnings or errors introduced by version changes. Backup your configuration files before performing any upgrade operations.