Port 3000 is already in use? Find the process on Windows
A dev server says a port is already in use. Use Windows PowerShell to find its current TCP listener, map the process ID to an app and choose a safe next step.
A local development server says port 3000 is already in use. Changing to 3001 can be a reasonable fix if you need both apps, but if you want to reuse 3000, identify the current listener first. Windows PowerShell can filter current TCP listeners by local port and show the owning process ID; Get-Process maps that ID to a process name. This documentation-based guide follows Microsoft’s published cmdlet references; it does not report a test on a particular PC.
Find the TCP listener
Run these commands in Windows PowerShell on the Windows computer where the server is running. Replace 3000 with the local port named in the startup error.
$port = 3000
$listeners = Get-NetTCPConnection -LocalPort $port -State Listen
$listeners |
Select-Object LocalAddress, LocalPort, State, OwningProcess Microsoft’s `Get-NetTCPConnection` reference documents the -LocalPort, -State and -OwningProcess parameters. A matching row describes a current local TCP endpoint in the Listen state. OwningProcess is the process ID (PID); LocalAddress and LocalPort identify the endpoint on this computer.
Turn the PID into a process name
Run this next in the same PowerShell window:
$listeners.OwningProcess |
Sort-Object -Unique |
ForEach-Object {
Get-Process -Id $_ | Select-Object Id, ProcessName
} Microsoft’s `Get-Process` reference documents -Id for looking up a process by PID. Sort-Object -Unique avoids repeating a process if it has listeners on more than one local address. If the process exits between the two commands, run the listener query again; the result is a snapshot, and PIDs can change.
The process name is a clue, not permission to stop it. If it is another copy of your own development server, stop it from the terminal that launched it or use the app’s normal stop control, then rerun the query. If you need both servers, configure the one you control to use another port. If the name is System, a service host, or unfamiliar, do not end it based only on this result; identify the service or ask your administrator.
If no TCP listener appears
First check the port number and confirm that the error refers to a local TCP port. If you want to inspect other TCP states, remove -State Listen from the first command. A non-listening endpoint is not the same thing as a server accepting new connections.
If the application uses UDP, query UDP endpoints instead:
$udp = Get-NetUDPEndpoint -LocalPort $port
$udp | Select-Object LocalAddress, LocalPort, OwningProcess Microsoft’s `Get-NetUDPEndpoint` reference documents the local-port and owning-process fields. You can map its OwningProcess values with the same Get-Process pipeline, replacing $listeners with $udp.
Also check where the server actually runs. In WSL 2’s default NAT mode, Windows can reach a Linux networking app through localhost, but the Linux process still belongs to the distro. If the bind error came from inside WSL, inspect the listener there rather than expecting a Windows process name. See Microsoft’s WSL networking guide . A process in a virtual machine or container can likewise have a different internal port from the one published on the Windows host.
Finally, one busy development port is different from system-wide TCP/IP port exhaustion. Microsoft’s Windows client troubleshooting guide covers the latter. If many applications are failing to create outgoing connections, investigate that broader symptom; changing Windows’ dynamic port range is not the first fix for a single listener.