Nginx won't start or reload? How to read the error and fix it

You changed a site's settings, and now Nginx won't reload, or worse, won't start. Nginx always says exactly what's wrong, with the file and line number. This guide shows the messages we saw and how to fix each one, plus the habit that keeps your sites online while you fix them.

We tested every case in this guide on Debian 13 with Nginx 1.26. We broke a working setup one way at a time, copied the real messages, and checked whether the site stayed online. Ubuntu works the same way.

The one habit: test, then reload

Always run this after a change, and never restart:

sudo nginx -t && sudo systemctl reload nginx

nginx -t checks every file. The reload runs only if the check passes. Here is what happened in our test with a missing ; in one site's file:

  • Reload: it failed, but Nginx kept running with the old settings. All sites stayed online.
  • Restart (stop, then start): Nginx stopped and couldn't start again. Every site on the server went offline because of one typo in one file.

Debian's service file also checks the settings before it starts Nginx. On a restart, though, that happens after the stop, so it only stops Nginx from starting broken. It doesn't keep your sites online.

1. Find the message

sudo nginx -t

If systemctl only says "Job for nginx.service failed", the details are here:

sudo journalctl -u nginx -n 30 --no-pager

Look for the line with [emerg]. It names the problem, the file and the line. These are the ones we saw.

2. A typo: unexpected "}"

[emerg] unexpected "}" in /etc/nginx/sites-enabled/shop:5

Almost always a missing ; at the end of the line before the one named. In our test, line 4 was root /var/www/shop without the ;, and Nginx complained about the } on line 5. Other messages of the same kind are unexpected end of file (a missing }) and unknown directive (a misspelled word, or a setting from a module you don't have).

3. A link to a file that's gone

[emerg] open() "/etc/nginx/sites-enabled/old" failed (2: No such file or directory) in /etc/nginx/nginx.conf:61

The files in sites-enabled are usually links to sites-available. Someone deleted or renamed the file in sites-available, and the link now points at nothing. Find links like that, and remove them:

sudo find /etc/nginx/sites-enabled -xtype l
sudo rm /etc/nginx/sites-enabled/old

4. A certificate that doesn't exist

[emerg] cannot load certificate "/etc/letsencrypt/live/shop.test/fullchain.pem": BIO_new_file() failed (... No such file or directory ...)

A site points at a certificate that isn't there, for example after certbot delete, or after copying a site's settings to a new server without its certificates. Either get the certificate again (see HTTPS with Let's Encrypt) or remove the HTTPS part from that site's file. List the certificates certbot has with sudo certbot certificates.

5. "Address already in use"

nginx: [emerg] bind() to 0.0.0.0:80 failed (98: Address already in use)

Another program already uses port 80 (or 443). Find out which:

sudo ss -ltnp 'sport = :80'

In our test, it was Apache: users:(("apache2",pid=3921,fd=3)). Some packages install and start Apache automatically. If you don't use it, stop it and keep it off:

sudo systemctl disable --now apache2
sudo systemctl start nginx

If it says nginx, an old Nginx is still running. sudo systemctl stop nginx, then check with pgrep nginx before you start it again.

6. Two "default" sites

[emerg] a duplicate default server for 0.0.0.0:80 in /etc/nginx/sites-enabled/dup:1

Only one site per port can have default_server on its listen line. Often it's the default site Debian ships, plus a new site that copied the same line. Remove default_server from one of them, or remove the link to the site you don't need: sudo rm /etc/nginx/sites-enabled/default.

7. A long site name

[emerg] could not build server_names_hash, you should increase server_names_hash_bucket_size: 64

A long server_name doesn't fit Nginx's default space for names. In /etc/nginx/nginx.conf, inside http { }, Debian already has the line, commented out. Turn it on and raise it:

server_names_hash_bucket_size 128;

A warning you shouldn't ignore

[warn] conflicting server name "shop.test" on 0.0.0.0:80, ignored

This is only a warning. nginx -t still says "successful", and Nginx reloads. But two files now claim the same site, and only the one that loads first is used. Files load in alphabetical order. In our test, an old copy called aaa-old took over the live site: visitors saw "OLD SITE" instead of the shop. When we renamed it zzz-old, the shop came back. Find the duplicates:

sudo grep -Rn "server_name" /etc/nginx/sites-enabled/

Remove the old one. Don't keep backups like shop.bak in sites-enabled: Nginx reads every file in that folder.

Quick list

  • Always: sudo nginx -t && sudo systemctl reload nginx. Never restart to apply a change.
  • unexpected "}": a missing ; on the line before.
  • open() ... sites-enabled ... No such file: a broken link. find /etc/nginx/sites-enabled -xtype l.
  • cannot load certificate: get the certificate again, or remove the HTTPS part.
  • Address already in use: ss -ltnp 'sport = :80', usually Apache.
  • duplicate default server: only one default_server per port.
  • conflicting server name: two files for one site. The first in alphabetical order wins.

Official sources

Next steps: if Nginx runs but shows errors, see fixing 502 and 504 errors and fixing 403 Forbidden. To set up several sites cleanly, see several websites on one server.

ServerNest is being built to test web server settings before it applies them, and to undo a change that breaks a site. Join early access to try it first.

← Back to the security blog