The Linux Page

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

Port in use prevents NGINX to start with a bind error.


I'm writing a test against nginx to verify the validity of a module. To make sure that each one of my test runs against a pristine version of nginx and my module, I decided to restart nginx each time. That's my own compiled version of the server, of course.

NGINX Bind Errors

Once in a while, this causes this bind error:

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

The fact is that if things go too fast then a previous instance of the socket will still be in the TIME_WAIT state.

Unsecure Fix (useful for testing!)

In order to avoid this problem and assuming you are using this option for a similar reason (i.e. you stop and restart nginx often) then you can use the option reuseport to avoid the bind error. This option appears on your listen line. Something like this:

listen reuseport;

It is always safe to use that option if that port is not accessible from the outside.

Security Considerations

If the port is public (such as 80 or 443) then you may want to weight the security implications of using the reuseport option. More or less, a TCP connection is actually stateless as far as the network stack is concerned. Because of that, an old connection (or connection attempt) that was directed to the previous server may instead send data to the new instance of the server without any way of really knowing that is happening. Because nginx handles the HTTP protocol only, it should not be a huge concern, but please look into it if you think you need to use reuseport on a public instance.

Not Testing?! What Gives?

Ports a service can listen on must be available at the time the binding happens. This means you can't have two services that listen on the same port.

For example, you may already have Apache listening on port 80. If that's the case, well.. NGinx just can't also listen on port 80. You must stop Apache or change the port used by NGinx.

One rather non-safe way of killing the other service using your port is to use fuser like so:

sudo fuser -k 80/tcp
sudo fuser -k 443/tcp

I do not really recommand using this command, but it's pretty effective!

A safer way is to look at your network services and see which one is using port 80 and 443. Then decide what to do. A clean stop is generally better than a violent kill.

sudo netstat -a64np | grep ':\(80\|443\).*LISTEN'

The name of the process will appear in the last column. For example if you have Apache running:

tcp6     0    0 :::80     :::*    LISTEN   808/apache2
tcp6     0    0 :::443    :::*    LISTEN   808/apache2

Now you can decide to stop Apache with:

sudo systemctl stop apache2

You can also kill it by first looking for the PID (the output of netstat also gave use the PID: 808) or using killall:

# Find PID
ps -ef | grep apache
www-data 26368 808  0 23:37 ?  00:00:01 /usr/sbin/apache2 -k start
kill 808

# Using killall (not recommended)
killall apache2

Note: I do not recommend killall because it's going to kill all the processes that match that name and that could be more than you expected.