Ffile2fix
Sign in Get started

Fix "nginx: configuration file test failed"

nginx: [emerg] unexpected "}" in /etc/nginx/sites-enabled/example.com:42
nginx: configuration file /etc/nginx/nginx.conf test failed

nginx -t parses every included config file and stops at the first error it finds. The line just before "test failed" gives the file, line number and reason; fix that, run the test again and repeat until it reports "syntax is ok" and "test is successful".

Also appears as: nginx: [emerg] unknown directive "proxy_pas" in /etc/nginx/conf.d/app.conf:12 · nginx: [emerg] "server" directive is not allowed here in /etc/nginx/conf.d/site.conf:1 · nginx: [emerg] cannot load certificate "/etc/letsencrypt/live/example.com/fullchain.pem": BIO_new_file() failed · nginx: [emerg] duplicate location "/" in /etc/nginx/sites-enabled/default:30

Common causes

  • A missing semicolon or unbalanced brace, which often shows up as an error on a later line
  • A misspelled directive or one from a module that is not compiled in or loaded
  • A directive in the wrong context, such as server outside http or location outside server
  • A referenced file that does not exist: certificate, key, include or snippet
  • Duplicate server_name/listen defaults, duplicate location blocks or a second default_server
  • A stray backup file in sites-enabled or conf.d being included alongside the real config

How to fix it

  1. Run the test and read the [emerg] line. Run sudo nginx -t. The [emerg] line shows the exact file and line number; open it with sudo nano +42 /etc/nginx/sites-enabled/example.com.
  2. Look at the lines just before. An unexpected } or end of file usually means a missing semicolon or brace a few lines earlier. Check that every directive ends with ; and every { has a matching }.
  3. Fix unknown directives. Check spelling, then check whether the module is available with nginx -V 2>&1 | tr ' ' '\n' | grep module. Dynamic modules need a load_module line at the top of nginx.conf.
  4. Check referenced files. For cannot load certificate or open() failed errors, verify the path with sudo ls -l. If Certbot never issued the certificate, comment out the ssl lines, reload and issue it first.
  5. Clean up included files. Remove backups such as default.bak or site.conf~ from sites-enabled and conf.d, since include globs load them too. Use sudo nginx -T to print the full merged config.
  6. Reload only after success. When the test passes, run sudo systemctl reload nginx. A failed reload keeps the old config running, but a restart with a broken config takes the site down.

Shell

sudo nginx -t
sudo nginx -T | less          # full merged config with file markers
sudo nginx -t && sudo systemctl reload nginx

How to stop it happening again

  • Always chain nginx -t && systemctl reload nginx instead of restarting blindly
  • Keep sites-enabled limited to symlinks of real configs, with no backup files
  • Store configs in Git so you can diff and roll back a bad change
  • Validate edits before copying them to the server

Frequently asked questions

Is my site down when nginx -t fails?

Not if Nginx is already running; it keeps serving the last good config. It goes down only if you restart, or if it is stopped and cannot start with the broken file.

Why does the error point to a line that looks correct?

Nginx reports where parsing broke, not where the mistake is. A missing semicolon or quote on an earlier line makes the next line look wrong.

Why does nginx -t need sudo?

The test opens certificate keys, log files and the pid file, which are usually readable only by root. Without sudo you get permission errors that hide the real result.