Finding a process using a specific network port with the lsof command

  • Post by Nicolas Ramz
  • Mar 31, 2015
Finding a process using a specific network port with the lsof command

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.