Note
Access to this page requires authorization. You can try signing in or changing directories.
Access to this page requires authorization. You can try changing directories.
Applies to: ✔️ Windows VMs
Summary
This article explains how to troubleshoot Remote Desktop Protocol (RDP) connectivity problems caused by network security group (NSG) misconfigurations on Azure Windows virtual machines (VMs). Common causes include missing allow rules, rule priority conflicts, and conflicting rules between subnet-level and network interface (NIC)-level NSGs.
Symptoms
You experience one or more of the following symptoms when connecting to an Azure Windows VM through RDP:
- RDP connection times out or is refused.
- You receive "Remote Desktop can't connect to the remote computer" errors.
- RDP works from one source IP but not another.
- RDP stops working after NSG rule changes.
- A new VM is unreachable through RDP immediately after deployment.
Prerequisites
- Access to the Azure portal with at least Network Contributor role on the affected resource group.
- Azure CLI or Azure PowerShell installed for command-line troubleshooting.
- The VM must be in a Running state.
How NSG rule evaluation works
Before you start troubleshooting, it's important to understand how Azure evaluates NSG rules:
- Azure evaluates rules by priority. Azure processes rules in priority order, with the lowest number representing the highest priority. Evaluation stops when Azure finds a matching rule.
- Azure evaluates inbound and outbound rules separately. RDP connectivity requires an inbound allow rule on port 3389.
- You can apply NSGs at the subnet level and the network interface (NIC) level. When NSGs exist at both levels, inbound traffic must be allowed by both NSGs to reach the VM.
- Every NSG contains default rules that you can't delete. The default
DenyAllInBoundrule (priority 65500) blocks all inbound traffic that isn't matched by a higher-priority rule.
For more information, see How network security groups filter network traffic.
Identify the blocking NSG rule
Use Network Watcher IP flow verify
IP flow verify is the fastest way to determine which NSG rule blocks RDP traffic.
- In the Azure portal, search for and select Network Watcher.
- Under Network diagnostic tools, select IP flow verify.
- Configure the test:
- Virtual machine: Select the affected VM.
- Network interface: Select the VM's primary NIC.
- Protocol: TCP.
- Direction: Inbound.
- Local port: 3389.
- Local IP address: The VM's private IP.
- Remote IP address: The IP address you're connecting from.
- Remote port: Any available port (for example, 60000).
- Select Check.
The result shows whether traffic is Allowed or Denied, and the name of the NSG rule responsible.
You can also run IP flow verify with Azure CLI:
az network watcher test-ip-flow \
--resource-group myResourceGroup \
--vm myVM \
--direction Inbound \
--protocol TCP \
--local 10.0.0.4:3389 \
--remote 203.0.113.50:60000
Or with Azure PowerShell:
Test-AzNetworkWatcherIPFlow `
-NetworkWatcher $networkWatcher `
-TargetVirtualMachineId $vm.Id `
-Direction Inbound `
-Protocol TCP `
-LocalIPAddress 10.0.0.4 `
-LocalPort 3389 `
-RemoteIPAddress 203.0.113.50 `
-RemotePort 60000
View effective security rules
View the effective (combined) security rules applied to the VM's network interface to see how subnet-level and NIC-level NSG rules merge:
- In the Azure portal, go to Virtual Machines and select your VM.
- Expand Networking and select Network settings.
- Select the network interface name.
- Under Help, select Effective security rules.
Look for rules that affect port 3389 TCP inbound. Verify that an Allow rule exists with a higher priority (lower number) than any Deny rule that matches the same traffic.
Use Azure CLI:
az network nic list-effective-nsg \
--resource-group myResourceGroup \
--name myVMNic
Use Azure PowerShell:
Get-AzEffectiveNetworkSecurityGroup `
-NetworkInterfaceName myVMNic `
-ResourceGroupName myResourceGroup
Common NSG misconfigurations
RDP port 3389 not allowed in NSG
When you create a new VM, the default setting blocks all inbound traffic from the Internet unless you select to open RDP during deployment.
To add a rule to allow RDP:
In the Azure portal, go to Virtual Machines and select the VM.
Expand Networking and select Network settings.
Select Create port rule > Inbound port rule.
Configure the rule:
Setting Value Source Your IP address or range Source port ranges * Destination Any Destination port ranges 3389 Protocol TCP Action Allow Priority 300 (or another value lower than any conflicting deny rule) Name Allow-RDP Select Add.
Rule priority conflict
A higher-priority deny rule blocks RDP even when an allow rule exists. For example:
| Priority | Name | Port | Action | Result |
|---|---|---|---|---|
| 100 | DenyAll | * | Deny | Blocks all traffic, including RDP |
| 200 | AllowRDP | 3389 | Allow | Never evaluated (blocked by priority 100) |
Resolution: Change the priority of the allow rule to a value lower than the deny rule, or narrow the deny rule to exclude port 3389.
Subnet-level and NIC-level NSG conflict
When you apply NSGs at both levels, traffic must pass through both. A common misconfiguration is:
- Subnet NSG: Allows RDP (port 3389).
- NIC NSG: Has no allow rule for port 3389 (default
DenyAllInBoundblocks it).
Or the reverse:
- NIC NSG: Allows RDP (port 3389).
- Subnet NSG: Has a deny rule blocking port 3389.
Resolution: Ensure an allow rule for port 3389 TCP exists in both NSGs. Verify by using the effective security rules to see the combined result.
Source IP address restriction
If the allow rule specifies a source IP address or range, RDP connections from IP addresses outside that range are blocked.
Resolution: Verify that the source IP address of your RDP client is included in the rule's source. Use a service like What's My IP to confirm your public IP.
Service tag misconfiguration
Service tags represent groups of IP address prefixes. Using the wrong service tag can inadvertently block or allow traffic:
- Internet: All public IP addresses. Allows RDP from any internet source.
- VirtualNetwork: Addresses within the virtual network, peered virtual networks, and VPN-connected networks. Doesn't include public internet IPs.
- AzureLoadBalancer: Azure infrastructure health probes. Doesn't include user RDP traffic.
Resolution: If you intend to allow RDP from the internet, use the Internet service tag or a specific IP range as the source. Don't rely on VirtualNetwork for internet-based RDP access.
For more information about service tags, see Virtual network service tags.
Verify NSG rules with CLI and PowerShell
List NSG rules applied to a NIC
Use Azure CLI:
az network nic show \
--resource-group myResourceGroup \
--name myVMNic \
--query "networkSecurityGroup.id" \
--output tsv
az network nsg rule list \
--resource-group myResourceGroup \
--nsg-name myNSG \
--output table
List NSG rules applied to a subnet
Use Azure CLI:
az network vnet subnet show \
--resource-group myResourceGroup \
--vnet-name myVNet \
--name mySubnet \
--query "networkSecurityGroup.id" \
--output tsv
Add an RDP allow rule using CLI
Use Azure CLI:
az network nsg rule create \
--resource-group myResourceGroup \
--nsg-name myNSG \
--name AllowRDP \
--priority 300 \
--direction Inbound \
--access Allow \
--protocol Tcp \
--destination-port-ranges 3389 \
--source-address-prefixes 203.0.113.50 \
--description "Allow RDP from specific IP"
Add an RDP allow rule using PowerShell
Use Azure PowerShell:
$nsg = Get-AzNetworkSecurityGroup `
-ResourceGroupName myResourceGroup `
-Name myNSG
$nsg | Add-AzNetworkSecurityRuleConfig `
-Name AllowRDP `
-Priority 300 `
-Direction Inbound `
-Access Allow `
-Protocol Tcp `
-DestinationPortRange 3389 `
-SourceAddressPrefix 203.0.113.50 `
-SourcePortRange * `
-DestinationAddressPrefix * `
-Description "Allow RDP from specific IP"
$nsg | Set-AzNetworkSecurityGroup
Secure RDP access for production environments
Important
Exposing RDP port 3389 directly to the internet is a security risk and isn't recommended for production environments.
Use one of the following alternatives for secure remote access:
| Method | Description |
|---|---|
| Azure Bastion | Provides secure RDP or Secure Shell (SSH) access through the Azure portal over Transport Layer Security (TLS). No public IP is required on the VM. |
| Just-in-time (JIT) VM access | Opens RDP port only when needed and for a limited time. Requires Microsoft Defender for Cloud. |
| VPN gateway | Connects through a site-to-site or point-to-site VPN tunnel. RDP traffic stays on a private connection. |
| Azure Private Link | Access VMs through private endpoints without exposing them to the public internet. |