ByteScope

3389

Port 3389 · RDP

TCP/UDPIANA assignedRemote access

The Remote Desktop listener on Windows — the port that is already taken when the service will not start, and silently dropped when the client just spins.

Find what is using port 3389

Run the line for your platform. Each one names the process holding the port and the address it bound to, which is usually the whole answer.

Check it from outside the machine

`nmap -Pn -p 3389 host.example.com` tells you what the port looks like from where the client actually is, and `-Pn` skips host discovery so a host that ignores ping is still scanned. Nmap defines the three answers precisely: `open` means an application on the target is listening; `closed` means the host replied but nothing is listening there; `filtered` means a firewall, filter or other network obstacle is blocking the probe so nmap cannot tell which. For RDP that distinction is the whole diagnosis — `closed` sends you to the server (service stopped, `fDenyTSConnections` set to 1, `PortNumber` moved), `filtered` sends you to the Windows Firewall rule or the cloud security group. Add `--reason` to see whether a reset came back or nothing did, and `-sV` to have nmap read the handshake. Scan only hosts you are responsible for.

Why a connection to 3389 fails

What you seeWhat it means
The client spins, then shows the generic dialog listing three reasons: remote access is not enabled, the computer is turned off, or it is not available on the networkThat dialog is a catch-all and names none of the three. Walk the chain in order instead: `qwinsta` on the target for an `rdp-tcp` row in `Listen`; `netstat -ano | findstr ":3389"` for a LISTENING row; `fDenyTSConnections` set to `0`; then the firewall. Each step eliminates one of the reasons the dialog refuses to choose between.
The connection is refused immediately — the handshake gets an instant resetReachable host, nothing listening. `TermService` is stopped, Remote Desktop is disabled (`fDenyTSConnections` is `1`, possibly held there by a Group Policy that overrides the Settings checkbox), or `PortNumber` under `WinStations\RDP-Tcp` was changed so the listener is somewhere else entirely. `qwinsta` distinguishes the last case in one line: the listener exists but is not on the port you dialled.
The client waits many seconds and then reports a timeoutNothing answered at all, which is a drop rather than a refusal. Inbound Remote Desktop rules in Windows Firewall, a cloud security group or network security group, or a network ACL somewhere in between. A refusal is instant and a drop is slow, so the delay is itself the evidence; `nmap --reason` confirms it by reporting `filtered` rather than `closed`.
Only one usage of each socket address (protocol/network address/port) is normally permittedWindows error 10048, the local spelling of `EADDRINUSE`: something else grabbed 3389 before Remote Desktop Services started. Follow Microsoft's sequence — `netstat -ano | findstr ":3389"` for the PID, then `tasklist /svc | findstr "<pid>"` for the service behind it. If the owner is not `TermService`, the recommended fix is to move that other program, not to move RDP.
netstat shows nothing on 3389 and the listener still cannot bindThe port is reserved rather than occupied, which is the Windows shape of a permission failure: there is no process to find. `netsh interface ipv4 show excludedportrange protocol=tcp` lists the dynamic-port blocks Hyper-V, WSL2, Docker Desktop and the Windows NAT service claim at boot. If 3389 falls inside one, restart the service that claimed it — killing a process will not help, because there is not one.
The identity of the remote computer cannot be verified. Do you want to connect anyway?Expected on a stock machine and not a network fault: you are being offered the RDP self-signed certificate the service generated for itself, which no client can validate. It means the session is encrypted but unauthenticated, so it proves nothing about which host is on the other end. Issue a real certificate for the listener if that matters — and if the warning appears on a host that previously had a trusted certificate, treat it as a finding rather than a nuisance.
The session connects but is far laggier than the same link used to beTCP 3389 is open and UDP 3389 is not. Microsoft's UDP transport extension uses the same port number for graphics and multimedia, and when it cannot come up the session silently falls back to TCP only. Check that the firewall rule covers both protocols rather than just TCP.

What runs on port 3389

IANA registers 3389 as `ms-wbt-server` (Microsoft's abbreviation for Windows-Based Terminal) for both TCP and UDP, and Windows really does use both. TCP carries the session; Microsoft's UDP Transport Extension takes graphics and multimedia over UDP, and its specification states that the default port for incoming UDP connection requests on the terminal server is 3389 as well. That is why a firewall rule that opens only TCP can leave you connected but visibly worse over a lossy link. On Windows the listener is not an ordinary program. It belongs to Remote Desktop Services — the `TermService` service — which is hosted inside a `svchost.exe`, so looking the PID up with plain `tasklist` names `svchost.exe` and tells you nothing useful; `tasklist /svc` names the service instead. Three registry facts decide the rest. `fDenyTSConnections` under `HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Terminal Server` is `0` when Remote Desktop is enabled and `1` when it is not, and a Group Policy can hold it at `1` whatever the Settings checkbox shows. `PortNumber` under `...\Terminal Server\WinStations\RDP-Tcp` is what actually chooses the port. And `qwinsta` tells you whether the `rdp-tcp` listener ever reached the `Listen` state, which is a different question from whether the service is running. Outside Windows the same number is used by third-party servers such as xrdp, so a Linux host answering on 3389 is running one of those, not a Microsoft component.

Should port 3389 face the internet?

Do not put 3389 on the public internet. The history here is specific rather than theoretical: CVE-2019-0708, "BlueKeep", was a pre-authentication remote code execution flaw in Remote Desktop Services on Windows 7, Server 2008 and Server 2008 R2 — wormable, because it needed no credentials, no user interaction and no social engineering, only the ability to reach a vulnerable listener. Microsoft shipped fixes for out-of-support releases too, and noted that Network Level Authentication was a partial mitigation precisely because it forces authentication before the vulnerable code runs. Moving the listener with `PortNumber` is not a defence: Microsoft's own troubleshooting guidance explicitly does not recommend running RDP on another port, and a scanner that fingerprints services finds it regardless. Nor is the TLS warning you click past protection — the certificate is normally the machine's own RDP self-signed certificate, generated by the service and filed under Remote Desktop in the computer certificate store, so accepting it verifies nothing about the host you are about to type a domain password into. Put RDP behind a VPN, an RD Gateway or a jump host, restrict it by source address, require Network Level Authentication, and if identity matters, replace the self-signed certificate with an issued one the client will actually validate.

Service
RDP
Transport
TCP/UDP
Registry
IANA assigned
Category
Remote access

Tools on this site

All of these run in your browser — nothing is uploaded.

Related ports

Ports people usually end up checking in the same session as 3389.

Frequently asked questions

Why does the command show nothing when the port is clearly in use?

Almost always permissions. lsof and ss list the socket but hide the owning process when it belongs to another user, so a server started by a system account, by a container runtime or by launchd shows up as an anonymous listener until you re-run the command with sudo. On Windows the opposite happens: netstat shows nothing at all, yet a bind still fails, which means the port sits inside a range that Hyper-V, WSL2 or Docker Desktop reserved at boot.

Is it safe to kill whatever is holding the port?

Look at what it is first. An orphaned dev server is safe to kill; a database with a write in flight is not, and neither is a system service that something else depends on. If the owner is a container, stop the container instead — killing the process the host sees only makes the runtime restart it. When the process is something you need, moving your own service to another port is the faster fix.

Why can I reach the port locally but not from another machine?

The listener bound to 127.0.0.1 rather than 0.0.0.0. The probes on every page print the bound address next to the process for exactly this reason: a loopback bind is reachable from the machine itself and from nowhere else, no matter how the firewall is configured. Many frameworks made that the default deliberately, so it is usually a flag rather than a bug. If the address is already 0.0.0.0 and it still fails, the next suspect is a host firewall or a cloud security group.

Does moving a service to an unusual port make it safer?

Barely. Internet-wide scanners sweep the whole port range continuously, so an unusual number buys hours, not safety, and it costs you every colleague who now has to remember it. It does cut the noise in your logs from opportunistic scans of the default port, which is a real if modest benefit. Authentication, a firewall that restricts source addresses, and not exposing the service at all are the measures that actually change the outcome.

Still stuck on port 3389? browse every port in the reference — or go back to the failure message you actually got, above.