LinuxLinux

bind: address already in use

Something already holds the port, or the kernel is still holding it from a previous process. How to identify which, and when SO_REUSEADDR is the right answer.

easy fix6 min read

the linux error
bind: address already in use

Error: listen EADDRINUSE: address already in use :::3000

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

OSError: [Errno 98] Address already in use

Do this first3 steps

Run these in order. Each one tells you what its output means before you change anything.

  1. 1

    Find what holds the port

    sudo ss -tulpn 'sport = :3000'

    The users: field names the process and PID. Run it with sudo, because without it ss hides the process name for sockets owned by other users and the output looks empty of useful detail.

  2. 2

    If nothing owns it, check for sockets still closing

    ss -tan 'sport = :3000' | head

    TIME-WAIT or FIN-WAIT entries with no listener mean the kernel is still holding the address from a previous process. This clears on its own within about a minute, and SO_REUSEADDR avoids the wait.

  3. 3

    Stop the process properly rather than killing it

    sudo systemctl stop nginx

    For anything under systemd, killing the PID invites the supervisor to restart it straight away, so the port is taken again before you can bind. Stop the unit instead.

All 9 sections

EADDRINUSE has two distinct causes and the fix differs:

  1. Another process is listening. Find it and stop it, or use a different port.
  2. No process is listening, and the kernel still holds the address. Sockets from a previous process are in TIME_WAIT.

One command separates them.

Find the listener

sudo ss -tulpn 'sport = :3000'
Netid State  Local Address:Port  Peer  Process
tcp   LISTEN 0.0.0.0:3000        *:*   users:(("node",pid=48213,fd=21))

The sudo matters: without it ss will not show the process name for sockets owned by other users, and you get a confusing result that looks like nothing is there.

lsof is the alternative if you prefer it:

sudo lsof -i :3000 -sTCP:LISTEN

On older systems netstat -tulpn | grep :3000 still works; ss is the modern replacement and is significantly faster on a busy host.

Case 1: Something is listening

Identify it properly before you kill anything:

ps -p 48213 -o pid,ppid,user,etime,cmd
  PID  PPID USER  ELAPSED CMD
48213     1 app   02:41:19 node /srv/api/server.js

PPID 1 means it is supervised by systemd or was orphaned. If it is a systemd service, stop the unit rather than the process, or the supervisor restarts it immediately and the port is taken again before you can bind:

systemctl status 48213         # tells you which unit owns the PID
sudo systemctl stop myapi

For something genuinely stray:

kill 48213          # SIGTERM, lets it clean up
kill -9 48213       # only if it ignores SIGTERM

kill -9 gives the process no chance to close its listening socket or flush anything, which is how you end up with the TIME_WAIT situation below.

Avoid fuser -k 3000/tcp and kill $(lsof -t -i:3000) as reflexes. Both kill whatever is there without you having read what it is, which in a shared environment is how the wrong thing gets killed.

Case 2: Nothing is listening

sudo ss -tulpn 'sport = :3000'    # no output
ss -tan 'sport = :3000' | head
State       Local Address:Port    Peer Address:Port
TIME-WAIT   10.0.1.5:3000         10.0.1.9:54122
TIME-WAIT   10.0.1.5:3000         10.0.1.9:54123

The old process is gone and its connections are still winding down. TCP keeps the pair in TIME_WAIT for twice the maximum segment lifetime, 60 seconds on Linux, so that late packets from the old connection are not delivered to a new one.

Wait a minute and it clears. Or, better, make your server able to bind anyway.

SO_REUSEADDR is the real fix

A server should set SO_REUSEADDR before binding. It permits binding to a local address that has connections in TIME_WAIT, which is exactly the "I just restarted my service" case.

Most frameworks do this for you. Some do not:

sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
sock.bind(("0.0.0.0", 3000))
// Go sets SO_REUSEADDR on listening sockets by default.
ln, err := net.Listen("tcp", ":3000")

This does not let two processes listen on the same port. It only allows binding over lingering TIME_WAIT entries. SO_REUSEPORT is the different option that genuinely allows multiple listeners, used deliberately for load balancing across worker processes.

Do not reach for net.ipv4.tcp_tw_reuse. It is a client-side setting for outgoing connections, it does not help a listener, and tcp_tw_recycle, which people often mean, was removed from the kernel in 4.12 because it broke connections from behind NAT.

The IPv4 and IPv6 overlap

Error: listen EADDRINUSE: address already in use :::3000

The :::3000 is IPv6 [::]:3000. By default a socket bound to [::] also accepts IPv4 connections through the dual-stack mapping, so an IPv6 wildcard bind occupies the IPv4 port too. A second process binding 0.0.0.0:3000 then collides with something that does not appear when you only look at IPv4.

sudo ss -tulpn | grep :3000      # shows both families

Check both before concluding nothing is there.

Ports below 1024

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

If binding to 80 or 443 fails with permission denied rather than address in use, that is a different problem: privileged ports need CAP_NET_BIND_SERVICE. For a systemd service:

[Service]
AmbientCapabilities=CAP_NET_BIND_SERVICE

Worth knowing because the two errors get conflated, and running the whole service as root to work around it is a poor trade.

In containers

Inside a container the port is namespaced, so a conflict is usually on the host side of a published port:

docker run -p 3000:3000 myapp     # 3000 on the host must be free

Let Docker choose a host port when you do not care:

docker run -p 3000 myapp
docker port <container>

Two containers can both listen on 3000 internally without any conflict, as long as they publish to different host ports or none at all.

In a Kubernetes Pod, containers share a network namespace, so two containers in the same Pod listening on the same port do conflict. hostPort and hostNetwork reintroduce host-level conflicts and are worth avoiding for that reason among others.

A checklist

  1. sudo ss -tulpn 'sport = :PORT'. The sudo is required to see process names.
  2. Something listening → ps -p PID -o pid,ppid,user,etime,cmd and read it.
  3. PPID 1 → find the unit with systemctl status PID and stop that, not the PID.
  4. Nothing listening → ss -tan 'sport = :PORT' and look for TIME-WAIT.
  5. TIME_WAIT → wait ~60s, or set SO_REUSEADDR in the server.
  6. :::3000 in the message → an IPv6 wildcard bind is holding IPv4 too.
  7. Port under 1024 failing on permissions → CAP_NET_BIND_SERVICE, not root.
  8. Docker → the conflict is the host side of -p; omit the host port to auto-assign.

Frequently Asked Questions

How do I find which process is using a port on Linux?

sudo ss -tulpn 'sport = :3000', and the sudo is not optional: without it ss omits the process name for sockets owned by other users, so the output looks unhelpfully empty. sudo lsof -i :3000 -sTCP:LISTEN gives the same answer. On older systems netstat -tulpn | grep :3000 still works, though ss is the modern replacement and is much faster on a host with many connections. Follow up with ps -p <pid> -o pid,ppid,user,etime,cmd before you act on it.

Why is the port in use when nothing is listening?

Connections from the previous process are in TIME_WAIT. TCP holds the address and port pair for twice the maximum segment lifetime, 60 seconds on Linux, so that delayed packets from the old connection cannot be delivered to a new one that happens to reuse the same pair. ss -tan 'sport = :3000' shows the entries. It clears on its own, and the proper fix is for the server to set SO_REUSEADDR before binding, which is exactly what that option is for.

Does SO_REUSEADDR let two processes share a port?

No. It allows a bind to succeed when the address has connections lingering in TIME_WAIT, which is the restart case. Two processes cannot both hold a listening socket on the same address and port with it. The option that genuinely permits that is SO_REUSEPORT, which is a deliberate feature for spreading accepted connections across several worker processes, and it requires every listener to set it. Confusing the two leads people to expect a behaviour SO_REUSEADDR was never meant to provide.

Should I use tcp_tw_reuse to get rid of TIME_WAIT?

No. net.ipv4.tcp_tw_reuse applies to outgoing client connections and does nothing for a listening socket, so it will not fix this error. The setting people usually mean is tcp_tw_recycle, which was removed from the Linux kernel in 4.12 because it broke connections from clients behind NAT in ways that were very hard to diagnose. TIME_WAIT exists for a reason; SO_REUSEADDR on the server is the supported way to restart without waiting for it.

What does ":::3000" mean in the error message?

It is the IPv6 wildcard address [::] with port 3000. A socket bound there accepts IPv4 connections as well through dual-stack mapping, unless IPV6_V6ONLY is set, so an IPv6 wildcard bind occupies the IPv4 port too. A process then trying to bind 0.0.0.0:3000 collides with something that does not appear if you only inspect IPv4. Always look at both families, which sudo ss -tulpn | grep :3000 does by default.

Reference and practice

Learn the underlying concept

Other Linux errors