Ffile2fix
Sign in Get started

How to fix nginx bind() to 0.0.0.0:80 failed (Address already in use)

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

Nginx tried to listen on port 80 (or 443) but another process is already listening there, and only one process can own a port on the same address. Nginx cannot start until that process is stopped or moved to another port.

Also appears as: nginx: [emerg] bind() to [::]:80 failed (98: Address already in use) · nginx: [emerg] bind() to 0.0.0.0:443 failed (98: Address already in use) · nginx: [emerg] still could not bind() · Job for nginx.service failed because the control process exited with error code.

Common causes

  • Apache (apache2 or httpd) is installed and running on port 80
  • An old Nginx master process is still running, often from starting nginx manually instead of via systemctl
  • Another web server or container (Docker, Caddy, Traefik, a Node app) is published on 80/443
  • Duplicate listen directives, such as listen [::]:80 together with ipv6only=off, making Nginx bind the same port twice
  • A control panel service or a snap/package that started its own web server

How to fix it

  1. Find what owns the port. Run sudo ss -ltnp | grep -E ':80 |:443 ' or sudo lsof -i :80. The output shows the process name and PID.
  2. Stop and disable Apache if it is not needed. Run sudo systemctl stop apache2 && sudo systemctl disable apache2 (httpd on RHEL). If you need both, move Apache to another port such as 8080 and proxy to it.
  3. Clean up a stray Nginx. If the owner is nginx itself, run sudo systemctl stop nginx; if processes remain, sudo pkill nginx, then start it with sudo systemctl start nginx so systemd tracks it.
  4. Check Docker and other services. Run docker ps to see containers publishing 0.0.0.0:80. Change their port mapping or stop them.
  5. Remove duplicate listen lines. Search with grep -R "listen" /etc/nginx/ and make sure only one server block per address uses default_server, and that ipv6only=off is not combined with a separate IPv4 listen.
  6. Test and start. Run sudo nginx -t, then sudo systemctl start nginx and check systemctl status nginx.

Shell

sudo ss -ltnp | grep -E ':80 |:443 '
sudo lsof -i :80
sudo systemctl stop apache2 && sudo systemctl disable apache2
sudo pkill nginx   # only if stray nginx processes remain
sudo nginx -t && sudo systemctl start nginx
systemctl status nginx --no-pager

How to stop it happening again

  • Install only one web server on ports 80/443, or assign clear ports to each
  • Start and stop Nginx only through systemctl
  • Document which containers publish which host ports

Frequently asked questions

Can Apache and Nginx run on the same server?

Yes, but not on the same port. A common setup is Nginx on 80/443 proxying to Apache on 127.0.0.1:8080.

Why does nginx -t pass but start still fails?

nginx -t checks syntax only; it does not check whether the ports are free. The bind error happens when Nginx actually tries to listen.

What does "still could not bind()" mean?

Nginx retried binding a few times and the port stayed busy, so it gave up. Free the port as described above and start Nginx again.