When working with networked applications on Linux, you may encounter situations where a port is already in use, preventing your application from starting. Understanding which process is occupying a specific port is crucial for troubleshooting connection issues, resolving port conflicts, and effectively managing system services.
A port is a numerical identifier in networking, ranging from 0 to 65535, that allows multiple services to run on the same IP address:
- Well-known ports (0-1023): reserved for system services (HTTP: 80, HTTPS: 443, SSH: 22)
- Registered ports (1024-49151): used by user applications
- Dynamic/Private ports (49152-65535): temporary ports for client connections
In this article, we'll explore various methods to identify which process is using a particular port on Linux systems. These techniques are compatible with all major Linux distributions and offer varying levels of detail about network connections.
NOTE: Checking processes on ports below 1024 or seeing detailed process info often requires root privileges. Use
sudo
to ensure accurate results. Ports above 1024 can usually be checked without elevated permissions.
Using netstat
The netstat
(network statistics) command is a traditional tool for displaying network connections, routing tables, and network interface statistics.
NOTE: On some distributions,
netstat
may not be installed by default. You can install it via thenet-tools
package.
To find which process is using a specific port:
$ sudo netstat -tulpn | grep :<port_number>
Options explained:
-t
: Show TCP connections-u
: Show UDP connections-l
: Show only listening sockets-p
: Show the process ID and name-n
: Show numerical addresses instead of resolving hostnames
For example, to find which process is using port 8080:
$ sudo netstat -tulpn | grep :8080
tcp6 0 0 :::8080 :::* LISTEN 12345/java
This shows that a Java process with PID 12345 is listening on port 8080.
To see all listening ports:
$ sudo netstat -tulpn
Using ss
The ss
(socket statistics) command is the modern replacement for netstat
. It's faster and provides more detailed information about network connections.
TIP:
ss
is generally preferred overnetstat
as it's more efficient and actively maintained.
To find which process is using a specific port:
$ sudo ss -tulpn | grep :<port_number>
or to check IPv6 ports:
$ sudo ss -tulpn | grep tcp6
Options explained:
-t
: Show TCP sockets-u
: Show UDP sockets-l
: Show listening sockets-p
: Show process information-n
: Don't resolve service names
For example, to find which process is using port 3306:
$ sudo ss -tulpn | grep :3306
tcp LISTEN 0 80 0.0.0.0:3306 0.0.0.0:* users:(("mysqld",pid=1234,fd=10))
This shows that a MySQL process with PID 1234 is listening on port 3306.
To filter by state and port:
$ sudo ss -tulpn 'sport = :8080'
To see detailed information about a specific port:
$ sudo ss -tupn | grep :80
Using lsof
The lsof
(list open files) command lists all open files and the processes that opened them. Since network sockets are treated as files in Linux, lsof
can identify processes using network ports.
To find which process is using a specific port:
$ sudo lsof -i :<port_number>
For example, to find which process is using port 22:
$ sudo lsof -i :22
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
sshd 1234 root 3u IPv4 12345 0t0 TCP *:ssh (LISTEN)
sshd 1234 root 4u IPv6 12346 0t0 TCP *:ssh (LISTEN)
This shows that the SSH daemon with PID 1234 is listening on port 22.
To show only TCP connections:
$ sudo lsof -i TCP:<port_number>
To show only UDP connections:
$ sudo lsof -i UDP:<port_number>
To see all network connections for a specific protocol:
$ sudo lsof -i TCP
Output columns explained:
- COMMAND: Process name
- PID: Process ID
- USER: User running the process
- FD: File descriptor
- TYPE: Type of node (IPv4, IPv6)
- DEVICE: Device numbers
- SIZE/OFF: File size or offset
- NODE: Protocol (TCP, UDP)
- NAME: Port and connection state
Using fuser
The fuser
command identifies processes using files or sockets. It's particularly useful for quickly finding which process is bound to a port.
To find which process is using a specific port:
$ sudo fuser <port_number>/tcp
or for UDP:
$ sudo fuser <port_number>/udp
For example, to find which process is using port 443:
$ sudo fuser 443/tcp
443/tcp: 2345
This shows that process ID 2345 is using port 443.
To get more verbose output:
$ sudo fuser -v 443/tcp
USER PID ACCESS COMMAND
443/tcp: root 2345 F.... nginx
To terminate the process using a port:
$ sudo fuser -k 443/tcp
WARNING: Use the
-k
(kill) option with caution, as it will immediately terminate the process.
Using nmap
The nmap
(Network Mapper) tool can scan ports and identify services, though it requires installation on most systems.
NOTE:
nmap
may need to be installed separately and requires elevated privileges for certain scan types.
To scan a specific port on localhost:
$ nmap -sV -p <port_number> localhost
For example, to scan port 80:
$ nmap -sV -p 80 localhost
Starting Nmap 7.80 ( https://nmap.org )
Nmap scan report for localhost (127.0.0.1)
Host is up (0.000010s latency).
PORT STATE SERVICE VERSION
80/tcp open http Apache httpd 2.4.41
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 0.23 seconds
To scan multiple ports:
$ nmap -p 80,443,8080 localhost
Checking Specific Port Ranges
To find all processes using ports in a specific range:
Using ss
:
$ sudo ss -tulpn | awk '$5 ~ /:8[0-9]{3}/'
Using lsof
:
$ sudo lsof -i :8000-8999
Using netstat
:
$ sudo netstat -tulpn | grep -E ':(8[0-9]{3})'
Understanding Port States
When checking ports, you'll encounter different connection states:
- LISTEN: Process is waiting for incoming connections
- ESTABLISHED: Active connection between client and server
- TIME_WAIT: Connection closed, waiting to ensure remote TCP received acknowledgment
- CLOSE_WAIT: Remote endpoint has closed the connection
- SYN_SENT: Attempting to establish a connection
- SYN_RECV: Connection request received
For example, to see all established connections on port 80:
$ sudo ss -tn | grep ':80 .*ESTAB'
Finding Process Details
Once you've identified the PID, you can get more information about the process:
Using ps
:
$ ps -p <PID> -o pid,user,cmd
Using /proc
filesystem:
$ ls -l /proc/<PID>/exe
$ cat /proc/<PID>/cmdline
Example: For PID 12345:
$ ps -p 12345 -o pid,user,cmd
PID USER CMD
12345 www-data nginx: worker process
Since many ports are bound by system services, it's helpful to know how to identify the service managing a process. You can use systemctl
to find the service associated with a PID:
$ systemctl list-units --type=service --all | grep <PID>
# or
$ systemctl status $(ps -p <PID> -o unit=)
You can then find the service status using:
$ systemctl status <service_name>
Creating a Port Check Script
Here's a comprehensive script that checks which process is using a specified port across all available tools:
#!/bin/bash
# Color codes
GREEN='\033[0;32m'
RED='\033[0;31m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # no color
# Check if port number is provided
if [ -z "$1" ]; then
echo -e "${RED}Error: Please provide a port number${NC}"
echo "Usage: $0 <port_number>"
exit 1
fi
PORT=$1
# Validate port number
if ! [[ "$PORT" =~ ^[0-9]+$ ]] || [ "$PORT" -lt 1 ] || [ "$PORT" -gt 65535 ]; then
echo -e "${RED}Error: Invalid port number. Must be between 1 and 65535${NC}"
exit 1
fi
echo -e "\n${YELLOW}Searching for processes using port $PORT...${NC}\n"
command_exists() {
command -v "$1" >/dev/null 2>&1
}
found=false
# Check with `ss`
if command_exists ss; then
echo -e "${BLUE}=== Using ss ===${NC}"
result=$(sudo ss -tulpn 2>/dev/null | grep ":$PORT ")
if [ -n "$result" ]; then
echo "$result"
found=true
else
echo -e "${RED}No process found${NC}"
fi
echo ""
fi
# Check with `netstat`
if command_exists netstat; then
echo -e "${BLUE}=== Using netstat ===${NC}"
result=$(sudo netstat -tulpn 2>/dev/null | grep ":$PORT ")
if [ -n "$result" ]; then
echo "$result"
found=true
else
echo -e "${RED}No process found${NC}"
fi
echo ""
fi
# Check with `lsof`
if command_exists lsof; then
echo -e "${BLUE}=== Using lsof ===${NC}"
result=$(sudo lsof -i ":$PORT" 2>/dev/null)
if [ -n "$result" ]; then
echo "$result"
found=true
else
echo -e "${RED}No process found${NC}"
fi
echo ""
fi
# Check with `fuser`
if command_exists fuser; then
echo -e "${BLUE}=== Using fuser ===${NC}"
result=$(sudo fuser -v "$PORT/tcp" 2>&1 | grep -v "Cannot stat")
if [ -n "$result" ] && ! echo "$result" | grep -q "specified protocol"; then
echo "$result"
found=true
else
echo -e "${RED}No process found${NC}"
fi
echo ""
fi
# Summary
if [ "$found" = true ]; then
echo -e "${GREEN}✓ Port $PORT is in use${NC}"
else
echo -e "${YELLOW}✗ Port $PORT appears to be free${NC}"
fi
Usage:
$ chmod +x check-port.sh
$ ./check-port.sh 8080
Common Use Cases
Monitoring Ports in Real Time
It may be useful to monitor port usage to see live changes, which is helpful for debugging applications or services that start/stop frequently. You can use the watch
command with the examples shown above to achieve this:
$ watch -n 5 "sudo ss -tulpn | grep :8080"
This will re-run the ss
command and refresh the output in the terminal every five seconds.
Finding Web Server Ports
# Apache/Nginx on port 80
$ sudo lsof -i :80
# Application servers
$ sudo lsof -i :8080,8000,3000,5000
Finding Database Ports
# MySQL/MariaDB
$ sudo lsof -i :3306
# PostgreSQL
$ sudo lsof -i :5432
# MongoDB
$ sudo lsof -i :27017
# Redis
$ sudo lsof -i :6379
Finding All Listening Ports
$ sudo ss -tulpn | grep LISTEN
or
$ sudo lsof -i -P -n | grep LISTEN
Checking Ports in Docker Containers
To check which ports are being used by Docker containers, you can use the following commands.
List all running containers and their port mappings:
$ docker ps
Inspect a specific container:
$ docker inspect <container_id> | grep -i "port"
Check which container uses a host port:
$ docker port <container_name_or_id>
Troubleshooting
- Permission denied: Use
sudo
to see processes owned by the system or other users - No output: The port might be in use on IPv6 (
tcp6
) instead of IPv4 - check both - Firewall or SELinux: Ensure no security policies are blocking access to the port
- Even when some ports may appear free, their access could be blocked by firewall rules (
iptables
,firewalld
) or SELinux policies.
- Even when some ports may appear free, their access could be blocked by firewall rules (
- Port conflicts in Docker or Kubernetes: Containers can bind ports invisible to the host without
docker ps
orkubectl port-forward
Resolving "Address Already In Use" Errors
-
Identify the process:
$ sudo lsof -i :<port_number>
-
Get process details:
$ ps -p <PID> -f
-
Stop the process:
WARNING: Be careful when terminating service processes, since this can disrupt users or dependent applications.
$ sudo kill <PID>
or forcefully:
$ sudo kill -9 <PID>
-
Stop a service (if it's a system service):
$ sudo systemctl stop <service_name>
-
Verify the port is free:
$ sudo lsof -i :<port_number>
Further Reading & References
Core Networking & Process Tools
- IANA port assignments
fuser
- identifies processes using files or socketslsof
- lists information about files opened by processesnetstat
- displays network connections, routing tables, interface statistics, masquerade connections, and multicast membershipsnmap
- a network exploration tool and security scannerss
- a utility to dump socket statistics, providing more detailed information thannetstat
Process Management & System Utilities
ps
- reports a snapshot of current processessystemctl
- controls the systemd system and service manager
Text Processing Utilities
awk
- a programming language for pattern scanning and processinggrep
- searches for patterns within files