Port in use command generator

Choose an operating system, a protocol, and a port to get the exact commands that show which process owns it and how to stop it. The steps look before they stop, and the one-liners that skip that check are labelled. Every flag is explained, and the port is checked as a whole number before it reaches a command. Nothing you enter leaves your browser.

Updated

Worked example

Example input
{
  "port": 3000,
  "os": "macos",
  "protocol": "tcp",
  "action": "both",
  "variant": "both",
  "shell": "zsh",
  "signal": "TERM",
  "elevated": false
}
Output
Commands for TCP port 3000 on macOS (zsh), action: both

1. Find the process that owns the port
   Command (zsh):
       lsof -nP -iTCP:3000 -sTCP:LISTEN
   What it does: Lists the processes that are listening on TCP port 3000. The PID column is the number you need. -nP: two options together: n skips host name lookups and P skips port name lookups, so addresses and ports print as numbers. -iTCP:3000: selects Internet sockets that use TCP and port 3000. -sTCP:LISTEN: keeps only TCP sockets in the LISTEN state, so programs that are merely connected to the port are left out.

2. Check what that process is
   Command (zsh):
       ps -p PID_NUMBER -o pid,ppid,user,command
   What it does: Prints the owner and full command line of the process. Read it before you stop anything. Replace PID_NUMBER with the PID from the find step. -p PID_NUMBER: selects the process with this ID. -o pid,ppid,user,command: chooses the columns: process ID, parent process ID, owner, and the command with its arguments.
   Caution: If the command is not something you started, or the user is root or a system account, find out what it is before you go on. A matching port does not make the process yours to stop.

3. Check whether a Docker container publishes the port
   Command (zsh):
       docker ps
   What it does: Lists the running containers. Look in the PORTS column for :3000->. The number before the arrow is the port on this machine and the number after it is the port inside the container, as in 0.0.0.0:3000->80/tcp. If nothing in the column has :3000-> in it, no running container publishes the port. The command needs no flags.
   Caution: If a container matches, the port belongs to that container. Stop the container with docker stop and its name instead of stopping the process that Docker shows on the host. An entry with no arrow, such as 3000/tcp, is exposed inside the container but not published. If the column shows a range such as 8000-8002->8000-8002/tcp, every port inside the range is published.

4. Stop the process politely
   Command (zsh):
       kill -TERM PID_NUMBER
   What it does: Sends TERM to the process you inspected. Replace PID_NUMBER with the PID. -TERM: sends the TERM signal, which asks the program to shut down and lets it clean up. It is also the signal kill sends when you name none.
   Caution: Give the program a few seconds to shut down, then run the check again. Stopping a process owned by another user needs sudo.

5. Check that the port is free
   Command (zsh):
       lsof -nP -iTCP:3000 -sTCP:LISTEN
   What it does: Runs the check again. No output means nothing is on port 3000 any more. If the owner is back with a new PID, something restarted it. -nP: two options together: n skips host name lookups and P skips port name lookups, so addresses and ports print as numbers. -iTCP:3000: selects Internet sockets that use TCP and port 3000. -sTCP:LISTEN: keeps only TCP sockets in the LISTEN state, so programs that are merely connected to the port are left out.

6. Escalate only if the process is still running
   Command (zsh):
       kill -KILL PID_NUMBER
   What it does: Forces the process to end. Use it only after the check shows the port is still taken. Replace PID_NUMBER with the PID. -KILL: sends the KILL signal, which the program cannot catch, block, or ignore, so it gets no chance to clean up.
   Caution: KILL cannot be caught or ignored, so the program cannot flush buffers, close connections, or remove lock and socket files. Prefer TERM, and use KILL only if the process stays up.

7. One-liner with lsof: stop whatever is listening, without showing it first
   Command (zsh):
       kill -TERM $(lsof -t -nP -iTCP:3000 -sTCP:LISTEN)
   What it does: Finds the PIDs that listen on TCP port 3000 and sends TERM to all of them in one go. If nothing is listening, kill reports an error and does nothing. -TERM: sends the TERM signal, which asks the program to shut down and lets it clean up. It is also the signal kill sends when you name none. $( ... ): runs the command inside first and puts the PIDs it prints into the kill command. -t: terse output: prints only the process IDs, one per line, with no header. -nP: two options together: n skips host name lookups and P skips port name lookups, so addresses and ports print as numbers. -iTCP:3000: selects Internet sockets that use TCP and port 3000. -sTCP:LISTEN: keeps only TCP sockets in the LISTEN state, so programs that are merely connected to the port are left out.
   Caution: This stops every process that matches, without showing you the list first. If you are not sure what owns the port, use the inspect-first steps. Run the find command again afterwards to confirm.

Notes
- Replace PID_NUMBER with the number from the PID column of the find step, or enter the PID in the PID field to fill it in. The placeholder is not a number on purpose: pasted unchanged, the command fails instead of stopping something else.
- Check what owns the port before you stop it. A process on a port is not always yours: it can be a system service, a database, or a container runtime.
- Do not stop Docker, a database service, or a system process just to free a port. If a container publishes the port, stop the container. If the owner is something you need, change the port your app uses instead.
- Prefer TERM before KILL. TERM is the default signal of kill and lets a program shut down cleanly. KILL cannot be caught, blocked, or ignored, so the program cannot clean up.
- Processes owned by another user, and system services, need sudo to be seen or stopped. Turn on elevated to add sudo to the commands that need it.
- If the port is taken again within seconds, something restarted the process. Check its parent in the PPID or ParentProcessId column and stop the parent, such as a file watcher or a process manager, instead.
- If several processes share the port, such as the workers of one server or an IPv4 and an IPv6 listener, the one-liner stops all of them. Run the find command first to see how many there are.

The example asks for everything on TCP port 3000 on macOS with zsh. Step 1 lists what is listening, and the PID column holds the number you need. Step 2 shows the owner and the full command of that process, and step 3 lists the running Docker containers, so you can see whether one publishes the port in its PORTS column. Read all three before you go on.

Steps 4 to 6 are the inspect-first way to stop it. They use PID_NUMBER because the tool does not know the PID yet. It is not a number on purpose, so a command pasted unchanged fails instead of stopping something else. Enter the PID in the PID field to fill it in. Step 4 sends TERM, step 5 runs the check again, and step 6 sends KILL, which you need only if the process is still there.

Step 7 is the one-liner. It sends TERM to every process that listens on the port without showing you the list first, so it is labelled and kept apart. Each step explains its own flags.

How to use it

  1. Enter the port

    Type one port from 1 to 65535, such as 3000. Spaces around it are fine. Ranges, lists, names such as http, and anything that is not a whole number are rejected, so nothing odd can end up in a command.

  2. Choose your system and shell

    Pick macOS, Linux, or Windows, then your shell. On macOS and Linux, bash and zsh get the same commands. On Windows, PowerShell uses cmdlets and cmd uses netstat and taskkill. Choose TCP unless the program uses UDP.

  3. Choose what you need

    Find lists the owner of the port. Free adds the steps to stop it, and both shows everything. The default shows the inspect-first steps and the one-liners, each labelled. Pick inspect-first to leave the one-liners out.

  4. Run the find command and read the owner

    Copy the first command into your terminal and note the PID. Then run the inspect command and read what the process is. macOS and Linux show the owner and the full command line, PowerShell shows the name, parent, and full command line, and cmd shows only the image name. If you do not recognise the process, stop here and find out what it is.

  5. Stop the process, then check

    Enter the PID in the PID field, or replace PID_NUMBER yourself. Run the TERM command, wait a few seconds, and run the check again. Use the KILL step only if the process is still there.

  6. Add administrator rights if the output is empty

    If a port is clearly taken but the find command prints nothing, the owner may belong to another user. Turn on elevated to add sudo on macOS and Linux, or open the terminal with Run as administrator on Windows.

How it works

The generator builds commands from fixed templates. It rebuilds the port and the PID from validated whole numbers and inserts nothing else from your input, so there is nothing to inject. These are the rules.

  1. Port and PID. The port is one whole number from 1 to 65535, written as a number or as ASCII digits with spaces around them. Ranges, lists, names, signs, decimals, leading zeros, and other digit scripts are rejected. A PID must be a positive whole number, and PID 1 on macOS and Linux and PID 4 on Windows are refused.
  2. Choices. Operating system, protocol, action, variant, shell, and signal come from closed lists. The shell must suit the system: bash or zsh on macOS and Linux, PowerShell or cmd on Windows.
  3. Finding on macOS and Linux. lsof -nP -iTCP:PORT -sTCP:LISTEN. In the lsof documentation, -i selects Internet sockets by protocol and port, -s PROTOCOL:STATE limits them to sockets in the named state, -n and -P stop name lookups, and -t prints PIDs only. TCP gets the LISTEN filter. UDP has no LISTEN state to filter on, so lsof -nP -iUDP:PORT also lists clients that send to the port. On Linux the first choice is ss -ltnp 'sport = :PORT', or -lunp for UDP. The ss manual defines -l, -n, -p, and the sport filter on the local port.
  4. Stopping on macOS and Linux. kill -TERM PID comes first, and kill -KILL PID is a later step. POSIX defines kill with a signal name and SIGTERM as the default, and the Linux signal manual says SIGKILL cannot be caught or ignored. The Linux one-liner fuser -k -TERM PORT/tcp follows the fuser manual: -k sends SIGKILL unless -SIGNAL names another signal, and the tcp and udp name spaces match local ports.
  5. Windows. In cmd, netstat -ano shows all connections with the owning PID, and findstr /C:":PORT " searches for that exact text with its trailing space, so :30000 does not match. In PowerShell, Get-NetTCPConnection -LocalPort PORT -State Listen and Get-NetUDPEndpoint -LocalPort PORT return the owner, and Stop-Process -Id PID stops it. taskkill /PID PID ends a process and /F forces it. Windows has no signals, so the signal choice only decides whether taskkill gets /F. The PowerShell preview uses -WhatIf, which Microsoft documents as showing what would happen without running the cmdlet.
  6. Order. The inspect-first steps run in this order: find, inspect, stop, check, and escalate. One-liners are separate steps marked as such, and none is offered where it cannot be made exact, such as UDP on macOS.
  7. Privileges. With elevated on, sudo goes before every command that needs it, including the lsof inside $( ). By default, Linux requires a capability to bind a port below 1024, so the owner of a low port is often root. The lsof documentation notes that on some builds a user who is not root sees only their own files.
  8. Docker. docker ps lists the running containers. Its PORTS column shows each published port as the port on your machine, an arrow, and the port inside the container, such as 0.0.0.0:3000->3000/tcp, so the tool tells you to look for :PORT->. An entry with no arrow is exposed inside the container but not published.

The tool only produces text. It runs nothing, stores nothing, and sends nothing.

Limitations

  • It writes commands and never runs them, so it cannot tell you whether a port is in use right now. Run the find command on the machine you care about.
  • The commands follow each tool’s documentation. They have not been tested on every version of macOS, Linux, or Windows, and macOS ships its own builds of lsof and ps, so flags can differ between systems.
  • For TCP it lists only listening sockets. On Linux, a closed connection can keep a port busy for a short time, and no find command here shows that. The notes under the commands explain the case.
  • It handles one port at a time. A range, a list, or a name such as http is rejected.
  • The one-liners stop every process that matches. For UDP on macOS none is offered, because lsof also lists clients that merely send to the port.

Practical applications

Use it whenever a program fails to start because its port is taken, and you want the command for your system without searching.

  • Address already in use. A dev server stops with an EADDRINUSE error. Find the owner, read its command, and decide whether to stop it or move your app.
  • A server you forgot. A previous run is still alive in another tab or a background job. The inspect step shows its parent and, outside cmd, its full command line.
  • A container that owns the port. The Docker check tells you to stop the container instead of the process on the host.
  • A teammate on another system. Switch the operating system and shell to give them the matching commands for the same port.
  • Documentation and runbooks. Copy a checked command and its flag explanations instead of writing them from memory.

Common mistakes

  • Starting with KILL. It cannot be caught, so the program cannot flush buffers, close connections, or remove lock files. Send TERM, wait a few seconds, check the port, and escalate only if the process is still there.
  • Running lsof -i :3000 and stopping every PID it prints. Without the LISTEN filter the list includes browsers and other programs that are only connected to the port, and stopping them breaks things that were not in the way.
  • Stopping the process Docker shows on the host. When a container publishes the port, stop the container with docker stop and leave the host process to Docker.
  • Reading every line of findstr :3000 as the owner. Plain findstr also matches :30000 and lines where 3000 is the remote port. Look at the Local Address column and the State.
  • Concluding that the port is free because the command printed nothing. Without sudo, lsof may not list processes owned by other users, and a low port is often held by one.

Frequently asked questions

How do I find what is using a port on macOS?

Run lsof -nP -iTCP:3000 -sTCP:LISTEN, with your port in place of 3000. The PID column is the process ID. Then run ps -p PID -o pid,ppid,user,command to read the full command before you stop anything. Add sudo if the owner belongs to another user.

How do I kill the process using a port on Linux?

Find it with ss -ltnp 'sport = :3000', read its command with ps -p PID -o pid,ppid,user,command, and then run kill -TERM PID. Check the port again after a few seconds. If you are happy to stop everything on the port without seeing a list first, fuser -k -TERM 3000/tcp does it in one command.

What does lsof -nP -iTCP:3000 -sTCP:LISTEN mean?

The -n and -P options print addresses and ports as numbers instead of looking up names. The -iTCP:3000 option selects Internet sockets that use TCP and port 3000. The -sTCP:LISTEN option keeps only sockets in the listening state, so programs that are merely connected to the port are left out.

How do I free a port on Windows?

In PowerShell, run Get-NetTCPConnection -LocalPort 3000 -State Listen, note OwningProcess, and run Stop-Process -Id with that number. In cmd, run netstat -ano and filter for the port, then taskkill /PID with the number from the last column. If taskkill says it could not end the process, add /F to force it. Use a terminal opened with Run as administrator if the process belongs to another user.

Is kill -9 the right way to free a port?

Not as a first step. The number 9 is the KILL signal, which a program cannot catch, so it gets no chance to close connections or remove lock files. Send TERM first, wait a few seconds, check the port, and use KILL only if the process is still running.

Why does my server say the port is in use when the commands show nothing?

Three causes are common. The owner may belong to another user, so repeat the command with sudo or as administrator. A Docker container may publish the port. Run docker ps and look in the PORTS column for 3000 to the left of an arrow. On Linux, a bound TCP address can stay unavailable for a while after its socket closes unless the program sets SO_REUSEADDR, and that case has no listener to find.

Sources

  1. lsof documentation: options -i, -s, -n, -P, and -tOfficial documentation, checked 13 October 2026
  2. lsof documentation: frequently asked questions, listing as a non-root userOfficial documentation, checked 13 October 2026
  3. ss(8): socket statistics, options and filtersOfficial documentation, checked 13 October 2026
  4. fuser(1): identify and kill processes using files or socketsOfficial documentation, checked 13 October 2026
  5. POSIX kill utility: signal names and the SIGTERM defaultOfficial documentation, checked 13 October 2026
  6. signal(2): SIGKILL and SIGSTOP cannot be caught or ignoredOfficial documentation, checked 13 October 2026
  7. ip(7): privileged ports and local address reuseOfficial documentation, checked 13 October 2026
  8. Microsoft netstat reference: -a, -n, and -oOfficial documentation, checked 13 October 2026
  9. Get-NetTCPConnection: -LocalPort, -State, and OwningProcessOfficial documentation, checked 13 October 2026
  10. Stop-Process: -Id, -WhatIf, -Confirm, and -ForceOfficial documentation, checked 13 October 2026
  11. Microsoft taskkill reference: /pid and /fOfficial documentation, checked 13 October 2026
  12. docker container ls: listing running containers and their portsOfficial documentation, checked 13 October 2026

Port conflicts in Rig

Rig’s who_owns_port MCP tool runs the same lsof check, with netstat and tasklist on Windows. It returns each owner’s process ID, command, and name, plus a suggested free port. On macOS and Linux it also returns the working directory. Its kill_port tool sends SIGTERM, waits 400 ms, then sends SIGKILL if the port is still bound.

Related

https://userig.app/tools/port-in-use-command