How to Find and Kill Processes Using Specific Ports on Linux Terminal

When launching web servers, development environments (such as Node.js, Docker, or Python Flask), or database containers on a Linux system, you will frequently encounter the familiar binding error: Error: listen EADDRINUSE: address already in use :::8080. This occurs because another background daemon, rogue process, or unclosed terminal session is already bound to that exact TCP or UDP port number.

Rather than rebooting your machine or guessing process IDs, you can pinpoint the offending process and terminate it safely using standard Linux terminal utilities including lsof, ss, and fuser.

Method 1: Identify and Kill Processes Using lsof

The lsof (List Open Files) utility is the most versatile tool for inspecting network sockets and ports. Because network connections are handled as file descriptors in Linux, lsof provides detailed ownership and Process ID (PID) metrics.

  1. Open your terminal and execute the following command, replacing 8080 with your target port number:
sudo lsof -i :8080
  1. The terminal outputs a table detailing the active connection:
COMMAND   PID USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
node    24158 sammy   23u  IPv6 198273      0t0  TCP *:8080 (LISTEN)
  1. Identify the numeric value under the PID column (in this example, 24158).
  2. Send a graceful termination signal (SIGTERM) to allow the process to close connections cleanly:
kill 24158
  1. If the process fails to terminate within a few seconds (often due to being stuck in an unhandled loop or deadlock), issue a forced termination signal (SIGKILL):
kill -9 24158
  1. To combine lookup and termination into a single automated command, use:
sudo kill -9 $(sudo lsof -t -i:8080)

Method 2: Rapid Port Clearance Using fuser

If your primary objective is simply freeing up the blocked port immediately without manual PID lookups, the fuser utility is the fastest approach available on Debian, Ubuntu, and Red Hat systems.

  1. To see which PID is holding port 3000 over TCP:
sudo fuser 3000/tcp
  1. To view the process name and user details alongside the PID, add the verbose flag (-v):
sudo fuser -v 3000/tcp
  1. To automatically terminate all processes occupying that port in one step, pass the kill flag (-k):
sudo fuser -k 3000/tcp
  1. If the process refuses to exit gracefully, enforce a hard kill with:
sudo fuser -k -9 3000/tcp

Method 3: Inspecting Ports on Minimal Systems with ss

On minimal Linux server installations or slim container environments where neither lsof nor fuser is installed, the modern socket statistics utility ss is guaranteed to be present as part of the core iproute2 package.

  1. Run ss with parameters to filter listening TCP sockets and display process details:
sudo ss -tulpn | grep :8080
  1. The output displays the socket address alongside the process name and PID:
tcp   LISTEN 0      128          *:8080             *:*    users:(("python3",pid=14820,fd=4))
  1. Note the PID (14820) and terminate it using standard kill commands:
sudo kill -15 14820

Handling Persistent Zombie or Auto-Restarting Processes

If a port immediately reopens under a different PID after being killed, the process is being supervised by a system init daemon. Common culprits include systemd services, supervisor, or Docker restart policies.

  • To verify if systemd manages the process, run: systemctl status <PID>.
  • If supervised, stop the overarching service directly instead of killing the child PID:
sudo systemctl stop my-web-service
  • If running inside a background Docker container, find the container ID holding the port: docker ps --filter "publish=8080", then stop it using docker stop <container_id>.

Get the best tech tips delivered straight to your inbox.

Join thousands of readers mastering Apple, Google, Microsoft, and Linux.