You try to start your server and get hit with:

Error:listenEADDRINUSE:addressalreadyinuse:::3000

Or the Python equivalent:

OSError:[Errno98]Addressalreadyinuse

Something else is already using that port. Here’s how to find it and fix it.

Quick Fix: Find and Kill

On Linux/macOS

Find what’s using the port:

1
lsof -i :3000

Output:

CnOoMdMeAND12P3I4D5UdSeEvR2F2DuITPYvP6E1D2E3V4I5C6ESIZE/0OtF0FNTOCDPE*N:A3M0E00(LISTEN)

Kill it:

1
kill 12345

Or if it won’t die:

1
kill -9 12345

One-Liner to Kill Whatever’s on a Port

1
lsof -ti :3000 | xargs kill -9

The -t flag outputs just the PID, making it pipeable to kill.

Alternative: Using fuser

Some systems have fuser which is even more direct:

1
fuser -k 3000/tcp

This finds and kills whatever’s using TCP port 3000 in one command.

Using netstat or ss

If lsof isn’t available:

1
2
3
4
5
# Using ss (modern)
ss -tlnp | grep :3000

# Using netstat (older)
netstat -tlnp | grep :3000

Output:

LISTEN0511*:3000*:*users:(("node",pid=12345,fd=22))

Common Causes

1. Previous Process Didn’t Exit Cleanly

Your server crashed or you Ctrl+C’d it, but it didn’t release the port. The process might be a zombie or stuck in cleanup.

Fix: Kill it with the methods above.

2. Running Multiple Instances

You accidentally started your server twice, maybe in different terminals.

Fix: Kill the old one, or use a different port for development.

3. Docker Container Still Running

A container might be binding to the host port:

1
2
docker ps | grep 3000
docker stop <container_id>

4. Process Running in Background

You ran something with & or nohup and forgot about it:

1
2
jobs -l          # Check current shell's background jobs
ps aux | grep node  # Find all node processes

5. systemd Service

A service might be configured to use that port:

1
2
systemctl list-units --type=service --state=running | grep -i your-app
systemctl stop your-app

Preventing the Problem

Use Dynamic Ports in Development

Instead of hardcoding a port, let the OS assign one:

1
2
3
4
// Node.js
const server = app.listen(0, () => {
  console.log(`Server running on port ${server.address().port}`);
});
1
2
3
4
5
# Python
import socket
sock = socket.socket()
sock.bind(('', 0))  # OS assigns available port
port = sock.getsockname()[1]

Graceful Shutdown Handling

Make sure your app releases the port on exit:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
// Node.js
process.on('SIGTERM', () => {
  server.close(() => {
    console.log('Server closed');
    process.exit(0);
  });
});

process.on('SIGINT', () => {
  server.close(() => {
    process.exit(0);
  });
});

SO_REUSEADDR Option

Allow reusing a port that’s in TIME_WAIT state:

1
2
3
4
5
// Node.js - not directly supported, but the default behavior
// usually handles this. For raw sockets:
const net = require('net');
const server = net.createServer();
server.listen({ port: 3000, exclusive: false });
1
2
3
4
5
# Python
import socket
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
sock.bind(('', 3000))

TIME_WAIT State

Sometimes the port shows as in use even after killing the process. This is the TCP TIME_WAIT state — the kernel keeps the port reserved briefly to handle any straggling packets.

Check for it:

1
ss -tan | grep :3000

If you see TIME-WAIT, you can either:

  1. Wait — it clears in 30-60 seconds
  2. Use SO_REUSEADDR — lets you bind anyway (see above)
  3. Change the port — quickest workaround

Quick Reference

TaskCommand
Find process on portlsof -i :3000
Kill process on portlsof -ti :3000 | xargs kill -9
Find and kill (one command)fuser -k 3000/tcp
Check port statess -tan | grep :3000
List all listening portsss -tlnp

Summary

  1. Find what’s using the port: lsof -i :PORT
  2. Kill it: kill PID or kill -9 PID
  3. If it keeps happening, add graceful shutdown handling to your app
  4. For quick development, consider using port 0 to auto-assign

The error is almost always “something else is already running there.” Find it, kill it, move on.