Skip to content
🎉 Launch sale:50% off everything over $22 — automatically applied at checkout· ends Aug 2Shop the sale →
DevOps AI ToolKit
Newsletter
All guides
AI for NGINX By James Joyner IV · · 8 min read Last reviewed Jul 2026

Nginx Error: 'a duplicate default server for 0.0.0.0:80' — Cause, Fix, and Troubleshooting Guide

Quick answer

Fix nginx [emerg] a duplicate default server for 0.0.0.0:80: only one default_server is allowed per listen socket. Diagnose the clash and resolve it.

  • #nginx
  • #web-server
  • #troubleshooting
  • #config
Free toolkit

Stuck on this NGINX error? Get the free incident triage checklist

A one-page PDF — the exact steps to isolate, fix, and verify a production error like this one. No spam, unsubscribe anytime.

What this error means

a duplicate default server is a configuration-parse error NGINX raises at load time. Every listen socket (an ip:port pair such as 0.0.0.0:80) can have exactly one server block marked as the default for unmatched requests. When two or more server {} blocks each declare listen 80 default_server; — or two blocks implicitly claim the default because the first block to bind a socket becomes its default — NGINX cannot decide which one wins and refuses to start.

nginx: [emerg] a duplicate default server for 0.0.0.0:80 in /etc/nginx/conf.d/site-b.conf:2
nginx: configuration file /etc/nginx/nginx.conf test failed

The message cites the exact file and line of the second (conflicting) listen directive. A reload keeps the previous config running; a cold systemctl start nginx fails outright and the service stays dead, so no vhost on that socket serves traffic.

How the server responds

  • nginx -t fails with [emerg] a duplicate default server for 0.0.0.0:80.
  • systemctl reload nginx reports failure and the running config is unchanged.
  • A cold systemctl start nginx exits 1/FAILURE and the service does not come up.
  • The error points at a listen line in one included vhost file, not the whole config.
  • Appears right after adding or copying a new site into conf.d/ or sites-enabled/.
  • Can also fire for other sockets, e.g. a duplicate default server for [::]:443.

Testing the server configuration

Start with the validator; it names the file and line of the conflict.

sudo nginx -t

Find every default_server flag across the whole config tree:

grep -RnE 'listen[^;]*default_server' /etc/nginx/

Two or more hits for the same ip:port is your conflict. Because include order matters, dump the fully-assembled config and see which server blocks target the socket:

sudo nginx -T | grep -nE 'server_name|listen'

Inspect the specific file the error cited to confirm the flag:

sed -n '1,10p' /etc/nginx/conf.d/site-b.conf | cat -n

On Debian/Ubuntu, check whether the packaged default site is still linked:

ls -l /etc/nginx/sites-enabled/
grep -n default_server /etc/nginx/sites-enabled/default

Server configuration causes

  • Two default_server flags on the same socket — the most direct cause: listen 80 default_server; appears in two different server {} blocks, often across two files in conf.d/.
  • Copy-pasted vhost templates — a starter config carries default_server and gets duplicated for each new site, so every site claims the default.
  • Implicit default collision — before default_server existed, the first server on a socket was the implicit default. Mixing one explicit default_server with the historical implicit rule on the same socket can still collide across NGINX versions if two are flagged.
  • IPv4 and IPv6 treated as one socketlisten 80 default_server; and listen [::]:80 default_server; are separate sockets and are fine, but listen 80 default_server; plus a bare listen 0.0.0.0:80 default_server; are the same socket and clash.
  • The distro default site still enabled — Debian/Ubuntu ship /etc/nginx/sites-enabled/default with listen 80 default_server;; adding your own default_server site collides with it.
  • Included twice — the same vhost file symlinked or included from two paths, so its default_server is parsed twice.

The fix

Keep default_server on exactly one server block per socket and remove it from the rest. Suppose site-a.conf should be the default:

# /etc/nginx/conf.d/site-a.conf  — the ONE default for 0.0.0.0:80
server {
    listen 80 default_server;
    listen [::]:80 default_server;
    server_name _;
    return 444;               # or your real catch-all site
}
# /etc/nginx/conf.d/site-b.conf  — drop default_server here
server {
    listen 80;                # no default_server flag
    server_name site-b.example.com;
    root /var/www/site-b;
}

If the shipped default site is the unwanted one, disable it rather than editing packaged files:

sudo rm /etc/nginx/sites-enabled/default   # symlink only; the file stays in sites-available

If you want an explicit catch-all that returns a clean status for unknown hosts, make that single block the default and let every named vhost listen without the flag. Only one block per ip:port (and separately per IPv6 socket) may carry default_server.

Because default_server selection is bound to how the listen socket is set up, apply the change and revalidate:

sudo nginx -t && sudo systemctl reload nginx

A reload is sufficient for removing a duplicate flag. If NGINX was down because a cold start failed, use sudo systemctl start nginx (or restart) once nginx -t passes.

Safe configuration practice

  • default_server is per listen socket, not per server: IPv4 0.0.0.0:80 and IPv6 [::]:80 are different sockets and each may have its own default.
  • The default server also decides which cert/vhost serves requests whose Host header matches nothing — pick it deliberately, don’t let it fall to whichever file loads first.
  • Debian/Ubuntu’s sites-enabled/default is a frequent silent culprit; audit it before adding your own default site.
  • Grep the entire tree (grep -RnE 'default_server' /etc/nginx/) after any bulk vhost change; a single stray flag breaks the whole socket.
  • Avoid symlinking or includeing the same vhost from two places — the second parse re-declares the default.
  • Wire nginx -t into your deploy pipeline and alert on failed reloads; surface the failure on your monitoring dashboard so a bad vhost never reaches a cold restart.

See the NGINX category for more guides.

Free download · 368-page PDF

Fixed it? Get 500 NGINX & DevOps AI prompts — free

500 battle-tested, copy-paste AI prompts engineered by a senior systems engineer — every one with fill-in placeholders and safety/back-out notes. Drop your email and it's yours.

  • 500 prompts: Linux · Kubernetes · Terraform · OpenStack · GitLab · Docker · Monitoring · Incident Response
  • Instant PDF download — yours free, forever
  • Plus one practical AI-workflow email a week (no spam)

Single opt-in · unsubscribe anytime · no spam.

Did this fix your issue?

Free download · 368-page PDF

Get 500 Battle-Tested DevOps AI Prompts — Free

500 battle-tested, copy-paste AI prompts engineered by a senior systems engineer — every one with fill-in placeholders and safety/back-out notes. Drop your email and it's yours.

  • 500 prompts: Linux · Kubernetes · Terraform · OpenStack · GitLab · Docker · Monitoring · Incident Response
  • Instant PDF download — yours free, forever
  • Plus one practical AI-workflow email a week (no spam)

Single opt-in · unsubscribe anytime · no spam.