Today I could not launch a node server: the port my app was targeted was already in use. Fortunately Unix comes with very handy command line tools when it comes to finding which processes are using a specific port/address.
No matter what I did, refused to start with the error:
Error: listen EADDRINUSE
at errnoException (net.js:901:11)
at Server._listen2 (net.js:1039:14)
at listen (net.js:1061:10)
at Server.listen (net.js:1127:5)
The only way to fix the problem was to either use another port for my app (I didn’t want to do that) or find the process which used this port and kill it. I’m quite familiar with Unix command line but didn’t know how to do that. After the research, I found the lsof
command:
lsof - lists on its standard output file information about files opened by processes
At first it didn’t seem to be useful, but looking at the command line arguments, there is one that’s interesting:
-i
This option selects the listing of files any of whose Internet address matches the address specified in i. If no address is specified, this option selects the listing of all Internet and x.25 (HP-UX) network files.
Sounds like it will be useful after all!
Let’s try:
$ lsof -i4TCP
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
remoting_ 23282 leo 45u IPv4 0x06709db0 0t0 TCP 192.168.0.11:62186->64.233.167.125:https (ESTABLISHED)
sshd 98723 leo 4u IPv4 0x06f92db0 0t0 TCP 192.168.0.11:ssh->c-61-123-45-67.hsd1.co.comcast.net:30491 (ESTABLISHED)
sshd 98723 leo 5u IPv4 0x06f92db0 0t0 TCP 192.168.0.11:ssh->c-61-123-45-67.hsd1.co.comcast.net:30491 (ESTABLISHED)
node 98902 leo 3u IPv4 0x06615874 0t0 TCP *:http-alt (LISTEN)
node 98902 leo 17u IPv4 0x05504874 0t0 TCP localhost:6666 (LISTEN)
node 98902 leo 18u IPv4 0x051a9db0 0t0 TCP localhost:6667 (LISTEN)
node 98903 leo 17u IPv4 0x06615874 0t0 TCP *:http-alt (LISTEN)
node 98903 leo 18u IPv4 0x06f5f338 0t0 TCP 192.168.0.11:http->c-61-123-45-67.hsd1.co.comcast.net:27134 (ESTABLISHED)
node 98903 leo 19u IPv4 0x05504338 0t0 TCP 192.168.0.11:http->c-61-123-45-67.hsd1.co.comcast.net:54635 (ESTABLISHED)
Since at any time there are a lot of connections going on, this returns quite a lot of entries. But we may easily filter them, by using grep. Since the process is waiting for connections, it is likely in LISTEN
mode, so we can type:
$ lsof -i4TCP | grep LISTEN
node 98902 leo 3u IPv4 0x06615874 0t0 TCP *:http-alt (LISTEN)
node 98902 leo 17u IPv4 0x05504874 0t0 TCP localhost:6666 (LISTEN)
node 98902 leo 18u IPv4 0x051a9db0 0t0 TCP localhost:6667 (LISTEN)
node 98903 leo 3u IPv4 0x06615874 0t0 TCP *:http-alt (LISTEN)
That’s better: we have two different node processes listening. The good thing about the -i
option is that we may add the port as well:
$ lsof -i4TCP:8080 | grep LISTEN
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
node 98902 leo 3u IPv4 0x06615874 0t0 TCP *:http-alt (LISTEN)
node 98903 leo 17u IPv4 0x06615874 0t0 TCP *:http-alt (LISTEN)
We got it! These two processes are using port 8080, for some reason, pm2 didn’t correctly kill them. But we can easily do so ourselves with:
$ sudo kill -9 98902
Note that killing the first one will automatically kill the second process.