
Quick checks (first steps)
- Is the NGINX process running?
sudo systemctl status nginx - Has configuration syntax changed?
nginx -t - Are the expected ports open (80/443) locally and externally?
- Are site logs present and owned by the web user?
Always test configuration first: nginx -t
Runnginx -t after editing configuration. It validates syntax and reports errors so you don’t break the running service on reload.
Example: missing semicolon leads to an error
nginx -t failures:
- Syntax errors (missing
;or mismatched braces). - Directives placed in the wrong context (see next section).
- Missing files referenced by the config (certificates, include files).
Context errors: directives must be in the right block
Some directives are only valid in specific contexts (main, http, server, location). Putting an http { ... } block inside a server block will fail.
Example error when a directive is not allowed in this context
http is a top-level context in /etc/nginx/nginx.conf; server and location are nested inside it.
Common bad snippet that triggers errors (do not put http inside server):
Apply changes gracefully: reload vs restart
Prefer reloading the configuration so worker processes are replaced without dropping connections.- Reload (graceful):
nginx -s reloadorsudo systemctl reload nginx - Restart (full stop/start):
sudo systemctl restart nginx
Avoid
restart unless necessary. restart interrupts active connections briefly; reload applies configuration changes without downtime when nginx -t reports OK.Always run
nginx -t and then nginx -s reload (or systemctl reload nginx) if the test is successful. Use restart only for recovering failed workers or replacing the master process.Main configuration and logging
The global configuration file/etc/nginx/nginx.conf contains the http block and global logging settings. When hosting multiple sites, configure per-site logs to simplify debugging.
Example of key sections in /etc/nginx/nginx.conf:
worker_processes) unless you understand the performance implications.
Per-site logging (recommended)
Configure each virtual host to write to its own log directory. Create the directory before reloading NGINX — NGINX will create files but not parent directories. Example server block for a site with per-site logs:Verify reachability with curl
Usecurl from the server to check whether NGINX serves requests. This distinguishes between NGINX, DNS, and firewall issues.
Examples:
curl will fail — indicating the service is the problem:
Hosts file for local resolution
For testing or when the server needs to resolve its own hostname, add entries to/etc/hosts.
Example:
Firewalls and cloud provider security
Confirm both the server firewall (UFW, firewalld) and any cloud security groups (AWS Security Groups, GCP firewall rules, etc.) allow required ports (80 and 443). Exampleufw status output:
- Even if your site redirects HTTP to HTTPS, leaving port 80 closed prevents users visiting
http://example.comfrom being redirected. Best practice: keep both 80 and 443 reachable and redirect HTTP to HTTPS.
TLS & protocol considerations
Tune TLS settings carefully. Removing older TLS versions improves security but may block very old clients. Example TLS line to restrict to modern versions:Common errors and quick fixes
Final troubleshooting checklist
- Run:
nginx -tto validate syntax. - If
nginx -tis OK: reload withnginx -s reload(orsystemctl reload nginx). - Check logs in
/var/log/nginx/and per-site log directories. - Use
curllocally (curl -I) to verify a working response. - Verify firewall and cloud security groups allow required ports.
- If changing log paths, ensure directories exist and ownership is correct.
- Confirm TLS settings are compatible with your clients.
Links and references
- NGINX official docs: https://nginx.org/en/docs/
- Systemd service control: https://www.freedesktop.org/software/systemd/man/systemctl.html
- UFW documentation: https://help.ubuntu.com/community/UFW
- curl manual: https://curl.se/docs/manpage.html