The Error Message
You try to start or restart Nginx, but instead of a clean exit, your terminal spits out a wall of text. It usually looks like this:
nginx: [emerg] bind() to 0.0.0.0:80 failed (98: Address already in use)
nginx: [emerg] bind() to 0.0.0.0:80 failed (98: Address already in use)
nginx: [emerg] still could not bind()
What's Happening?
Linux networking is strict: only one application can claim a specific port at a time. Port 80 is the standard lane for HTTP traffic. If Nginx tries to open that lane and finds someone else parked there, it simply gives up.
Usually, the "squatter" is one of these:
- A ghost Nginx process that didn't shut down properly after a crash.
- Apache (httpd) running in the background—common on fresh VPS installs.
- A Docker container or a Node.js app mapping host port 80 to a container.
- Redundant
listen 80;directives in your own configuration files.
Step 1: Track Down the Culprit
You need to find the Process ID (PID) currently holding the port hostage. The ss command is the fastest way to do this on modern Linux systems.
Using ss (Recommended)
sudo ss -tulpn | grep :80
Expect output similar to this:
tcp LISTEN 0 511 *:80 *:* users:(("apache2",pid=1234,fd=4))
Using lsof
If you prefer lsof, run this command:
sudo lsof -i :80
The COMMAND and PID columns tell you exactly what you're up against. For example, if you see apache2 with PID 1234, you've found your bottleneck.
Step 2: Evict the Conflicting Process
Once you have the name or PID, you need to clear the path for Nginx.
Stop Apache or other services
If Apache is the one hogging the port, stop it and disable it so it doesn't return after a reboot.
# For Ubuntu/Debian
sudo systemctl stop apache2
sudo systemctl disable apache2
# For CentOS/RHEL
sudo systemctl stop httpd
sudo systemctl disable httpd
Kill orphaned Nginx processes
Sometimes Nginx hangs and leaves "zombie" processes behind. You can force-close every Nginx-related task with one command:
sudo killall -9 nginx
Use this with caution. It terminates all Nginx processes immediately without saving state.
Step 3: Audit Your Configuration
If no other software is running on port 80, your Nginx config might be fighting with itself. This often happens when two different site files in /etc/nginx/sites-enabled/ both try to claim default_server.
Check for syntax errors first:
sudo nginx -t
Search your config directory for duplicate port 80 declarations. Run this to see every file trying to use that port:
grep -r "listen 80" /etc/nginx/sites-enabled/
Make sure you don't have two different blocks trying to bind to the same IP and port combination.
Step 4: Fire Up Nginx
With the port finally clear, Nginx should start without complaints.
sudo systemctl start nginx
Verification
Double-check the status to ensure it stayed up. It should show active (running) in green text.
sudo systemctl status nginx
You can also confirm Nginx is the one now owning the port:
sudo ss -tulpn | grep :80
Pro-Tips for the Future
- Uninstall Apache: If you don't need it,
sudo apt purge apache2prevents it from ever auto-starting again. - Check Docker: If you use Docker, check
docker ps. A container mapped with-p 80:8080will block your host's Nginx. - Automate Tests: Never restart Nginx without running
nginx -tfirst. It saves you from downtime caused by simple typos.

