This page sums up the AVD connection paths series. Every item links to the place in the series with the reasoning, lab results and sources. Use it for design reviews, for the firewall request, and for the next “my remote desktop is slow” ticket.
- Part 1: the client decides which path you get
- Part 2: what the AVD settings really do to the path
- Part 3: the firewall rules you need, the ones you don’t, and three traps
- Part 4: why RDP Shortpath over private networks is luck, and a fix
- Part 5: the join type decides your sign-in firewall rules
- Part 6: reading the logs without being fooled
The queries and the lab setup are in the lab repo. If you need it as a table for the review meeting, the checklist as CSV has every item with area, expected state, link and an empty column for your result.
Client
-
The client offers UDP.
On Windows, the policy Turn Off UDP On Client is not enabled; on macOS, Use UDP where possible is on (or
ClientSettings.EnableAvdUdpSideTransportdeployed). (how) -
Windows App is recent enough.
2.0.559.0 or later for Multipath with UDP, 2.0.1069.0 or later for redundant TCP paths. (how)
-
Clients reach UDP 3478 on
51.5.0.0/16and UDP to the session host’s public NAT address.TCP 443 for the client FQDNs alone isn’t enough. (how)
-
You expect different paths per client.
The same network gives different clients different paths. (why)
-
The Connection Information dialog is read after a minute.
Not right after connecting, and its label is only a hint. (why)
-
The network test passes from the user’s network.
avdnettest.exeon Windows, avd-shortpath-test on macOS and Linux. They only test the network; a session can still stay on TCP. (how) -
A single session on WebSocket gets a reconnect first.
Investigate second. (why)
Host pool and session host
-
All four host pool RDP Shortpath settings are set to default or enabled.
ManagedPrivateUdp,DirectUdp,PublicUdp,RelayUdp. (how) -
The session host RDP Shortpath policy isn’t disabled for any path.
(how)
-
Select RDP transport protocols is unset or “Use both UDP and TCP”.
“Use only TCP” disables UDP for every session, and it’s often a leftover from old disconnect workarounds. (how)
-
STUN and TURN stay on.
Don’t switch one off to force the other path. Use the switches for troubleshooting only, one at a time. (why)
-
The ICE port range is set to default (49152-65535).
Or a narrowed range that matches the outbound firewall rule. (how)
-
Every change to the session host’s egress comes with a restart.
In the change plan, or in a maintenance window with drain mode. Then run
WVDAgentUrlTool.exe. (why)
Network: TCP and control plane
-
The session host FQDNs are allowed.
As listed on the required FQDNs page, ideally via the Azure Firewall FQDN tag
WindowsVirtualDesktopand service tags. (how) -
The entries without a matching tag have their own rules.
azkms.core.windows.neton TCP 1688,*.windows.cloud.microsoftand*.windows.static.microsofton TCP 443, and the certificate endpoints on TCP 80. (how) -
169.254.169.254and168.63.129.16are never proxied, intercepted, or redirected.(why)
-
No TLS inspection on AVD traffic.
If you inspect anyway (Azure Firewall Premium, an inspecting proxy), keep at least the Entra device and certificate endpoints out. (why)
-
WVDAgentUrlTool.exepasses on every session host.It doesn’t check wildcard entries. (how)
-
No rule or latency assumption expects the AVD gateway in the session host’s region.
Azure Front Door picks the gateway with the lowest latency for the client. (why)
Network: UDP
-
Session hosts reach UDP 3478 on
51.5.0.0/16.STUN and TURN. (how)
-
Session hosts may send UDP 1024-65535 outbound to any.
Needed for direct STUN paths. Without it: relay at best. (how)
-
20.202.0.0/16is gone from old rule sets.Replaced by
51.5.0.0/16. (why) -
Nobody blocks UDP 3478 as a “TURN only” block.
It removes STUN too. (why)
-
Hand-maintained prefixes (an NVA without service tags) match the
WindowsVirtualDesktopservice tag.Including
51.5.0.0/16(checked October 2026). (how) -
A bypass route on a private subnet comes with a NAT gateway.
WindowsVirtualDesktopwith next hop Internet needs a way out. (why) -
No NAT gateway or public IP on session hosts only for UDP.
Relay through Azure Firewall works. (why)
Not needed for a default setup
These show up in many firewall requests, and AVD doesn’t need them (part 3):
- Inbound TCP 3389 to session hosts
- A public IP on session hosts
- Inbound UDP for STUN or TURN
- UDP 3390 (only for the listener, see private networks)
Private networks: VPN and ExpressRoute
-
If users come over VPN or ExpressRoute, the listener is on.
Policy Enable RDP Shortpath for managed networks (Intune or Group Policy), then restart the session hosts. (how)
-
Get-NetUDPEndpoint -LocalPort 3390shows the listener.On the session host, after the restart. (how)
-
The host pool doesn’t disable RDP Shortpath for managed networks.
The most restrictive setting wins. (how)
-
UDP 3390 is allowed inbound to the session hosts, limited to your client ranges.
In the Windows Firewall, the NSG, Azure Firewall or the NVA in the hub, and the on-prem firewalls. (how)
-
Nothing in the path SNATs UDP 3390.
The session host has to see the real client address. Azure Firewall doesn’t SNAT network rule traffic to private ranges by default. Keep it that way. (how)
-
Every client range is known in routing, firewall rules, and NSGs.
Office networks and VPN pools, in the local network gateway or BGP. Symptom if not: timeouts and no firewall log entries at all. (why)
-
UDP over a private path doesn’t rely on luck.
Without the listener it depends on the client sending its checks first, and that works only sometimes. (why)
-
TURN isn’t silently dropped.
A split tunnel that routes TURN into the tunnel, or a TURN block at the breakout, makes ICE wait about 24 seconds before its checks (measured on the Mac). (why)
-
ExpressRoute is verified in your setup.
Same mechanism according to the docs, not tested in my lab. Look for
initialUdpType = ShortpathPrivate. (how) -
With Private Link for the AVD service, UDP over Private Link is opted in.
On the workspace or host pool. It only covers the managed-network options; STUN and TURN don’t work with Private Link. (how)
Identity
-
The join type is known before the first rule.
Entra joined, AD DS joined, or hybrid joined decides whether this section is one line or a page. (how)
-
Entra joined: no domain controller rules for AVD itself.
The FQDN list from part 3 covers the AVD side, and
WVDAgentUrlTool.exechecks it. (why) -
Locked-down networks allow the Microsoft Entra endpoints separately.
They are not in the AVD FQDN list. Add IDs 56 and 59 (sign-in and device registration) and 125 (certificate revocation) from Microsoft 365 URLs and IP address ranges. (how)
-
AD DS joined: the session hosts reach the domain controllers.
DNS 53, Kerberos 88, Kerberos password change 464, LDAP 389/636, Global Catalog 3268/3269, SMB 445, RPC 135 plus 49152-65535, time (NTP) 123. Check with
nltest /dsgetdc:<domain>andTest-NetConnection <dc> -Port 389. (how) -
Hybrid joined: the AD DS rules plus the registration endpoints in the system context.
enterpriseregistration.windows.net,login.microsoftonline.com, anddevice.login.microsoftonline.com(plusautologon.microsoftazuread-sso.comwith seamless SSO, and your security token service when federated). The proxy has to authenticate the machine, anddevice.login.microsoftonline.comandenterpriseregistration.windows.netstay out of TLS inspection. Check withdsregcmd /status. (how) -
FSLogix on Azure Files: SMB 445 reaches the storage account.
Ideally via a private endpoint, plus the identity rules for its authentication method. Check with
Test-NetConnection <storageaccount>.file.core.windows.net -Port 445. (how) -
With a private endpoint, the storage account name resolves to its private address.
If it doesn’t, check DNS first. (how)
Logs
-
Host pool diagnostics go to Log Analytics.
(how)
-
The Activity ID from the client is your filter.
It is the
CorrelationIdin every table. (how) -
Running sessions aren’t judged by
WVDConnections.TransportType.It is only final on the Completed row. (why)
-
Classify the path with
initialUdpTypeinShortpathEstablished.ShortpathPrivateis the listener,Shortpath_Relayed_UDPthe relay,Shortpath_Direct_UDPandShortpath_UDP_over_NATmostly direct. Only the firewall log tells you whether a direct path was public or private. (how) -
“The client didn’t offer UDP” is spotted early.
TransportTypeSelected=Unknown, orShortpathFallbackToGatewayTransportwithFallbackReason=NotSupported. (how) -
Windows Multipath sessions only count as UDP with proof.
A concrete
initialUdpTypeor theRemoteFX Networkcounters on the session host.ShortpathEstablishedalone doesn’t prove UDP. (why) -
Missing candidates are read as blocks.
No relay candidate means TURN is off or blocked; no server reflexive candidate means STUN is off or UDP 3478 is blocked. (how)
-
Every session is classified by path.
With the query from part 6, and single sessions with the decision tree. (how)
-
LastHeartBeatisn’t taken as a readiness signal after a network change.(why)
-
Firewall logs are read without UDP 3478 and in a short window around one connection.
A row from client to session host means the client checked; only rows the other way mean it didn’t. (how)
-
EstAvailableBandwidthKBpsis converted before you compare it with the client’s Mbps.It is kilobytes per second: multiply by 8 and divide by 1000. (why)
-
Example queries are tested in your own workspace.
The checkpoint names aren’t documented; I only observed them. (why)
Missing something on this list? Tell me in the comments and I’ll add it (with credit, of course).
This post reflects my personal opinion and lab results, not the position of Microsoft or my employer. Your feedback is always welcome!
Was this useful?
Noted. If you don't want to miss the next one: add yourself to the list ↓
Comments