Helpdesk: "Since the certificate renewal on Friday, nobody outside the office can connect through the gateway. Most users get 'the Remote Desktop Gateway server is temporarily unavailable', two get a certificate warning first, and from inside the office everything works. The MFA prompt on the phone also stopped showing up for one team. A forum post says to reinstall the RD Gateway role, turn off the Windows Firewall on the gateway, change the CAP and RAP to allow everyone to everything, and uninstall the NPS extension. Can we do that?"
Not yet. "RD Gateway not working" is almost never the role itself. A connection through Remote Desktop Gateway is a chain of separate checks, and each one fails with a different symptom: the public name resolves to the gateway and TCP 443 reaches it, the certificate it serves matches that name and is trusted and current on the client, the TSGateway service is listening, the user passes a connection authorization policy (CAP), the target passes a resource authorization policy (RAP), NPS and the MFA extension answer inside the RADIUS timeout, and the gateway can reach the target on 3389. Microsoft states the authorization part plainly: "For users to be granted access to network resources through a Remote Desktop Gateway, they must meet the conditions specified in one RD Connection Authorization Policy (RD CAP) and one RD Resource Authorization Policy (RD RAP)." Reinstalling the role throws away the CAPs, RAPs, and certificate binding you need to read, turning off the firewall proves nothing about the edge firewall in front of it, an allow-everything CAP and RAP opens the gateway to the internet, and removing the NPS extension removes MFA instead of fixing it. Work through it as a chain: which user, which client, which name, which error → does the public name reach the gateway on 443? → is the certificate it serves the right one, trusted, current, and checkable? → is the gateway service healthy and listening? → does the user pass a CAP? → does the target pass a RAP? → do NPS and the MFA extension answer in time? → can the gateway reach the target? → is UDP 3391 working, and why is Gateway Manager empty? Resolve-DnsName, Test-NetConnection, Test-Certificate, Get-RDCertificate, netsh http show sslcert, Get-CimInstance against the RD Gateway WMI classes, and Get-WinEvent on the TerminalServices-Gateway log are the sources for that chain. Change the certificate, the CAP, and the firewall at once and you'll never know which one was broken.
If the session host itself refuses users after the gateway lets them through with a licensing message, Remote Desktop Licensing Mode Is Not Configured covers that side. If NPS logs Event 6273 for the gateway's RADIUS requests, NPS Event 6273 Reason Code 16 or 22 covers reason codes. This post covers "users can't connect through a Windows Server RD Gateway (usually from outside the network): 'temporarily unavailable', a certificate expired or untrusted warning, an authorization failure, no MFA prompt, a session that fails after authorization, or an empty RD Gateway Manager, and you need a read-first path before you reinstall the role, replace the certificate, open the policies, or change NPS."
TL;DR
-
Inside working proves little. Internal clients may skip the gateway entirely:
BypassLocal"Indicates whether authorized remote users bypass the RD Gateway server for local connections." Test from outside (Step 2). - The certificate has to match the name clients type. Microsoft: "The name of the certificate must match the FQDN used to access RD Gateway" (Step 3). A renewed certificate that isn't bound to 443 is still the old one.
- Two policies, two events. A CAP failure is event 201, a RAP failure is event 301; read the TerminalServices-Gateway log before you touch either (Steps 5 and 6).
- MFA needs time and the right methods. Microsoft's RD Gateway guide says to change the RADIUS timeout "from 3 to a value between 30 and 60 seconds", and SMS codes don't work through the gateway (Step 7).
- Authorized but not connected is the target, not the gateway. Event 304 means the user passed both policies and the gateway couldn't reach the computer (Step 8).
- UDP 3391 is a second transport, not the only one. Read which transport live connections use before you blame UDP (Step 9).
Where in the chain did it break?
| Step | What should be true | Typical symptom when it breaks |
|---|---|---|
| 1. Symptom captured | Which user, which client and network, which gateway name, which exact message, since when | "The gateway is down" with no user, name, or time written down |
| 2. Name and TCP 443 | The public name resolves to the gateway's public address and 443 reaches it from outside | Works inside, fails outside; "temporarily unavailable" for everyone outside |
| 3. Certificate | The certificate served on 443 matches the name, is trusted by the client, is current, and its revocation can be checked | Certificate expired, untrusted, or name mismatch warnings; some clients fail, others don't |
| 4. Gateway service | TSGateway running, listening on 443 (and 3391), configured, under its connection limit | Every connection fails at once, including from inside through the gateway |
| 5. CAP | The user (and, if set, the client computer) is in a group of an enabled CAP | Event 201; "not authorized" before any session starts |
| 6. RAP | The target name, as typed, is in a RAP's resource list for that user, on that port | Event 301; works by IP or FQDN, fails by short name |
| 7. NPS and MFA | The central NPS answers the gateway inside the timeout, and the extension can reach Microsoft Entra ID | No phone prompt, prompt arrives late, or "temporarily unavailable" after the password |
| 8. Gateway to target | The gateway reaches the target on 3389, and the target accepts the user | Event 304; or the session host's own error after authorization |
| 9. UDP and monitoring | UDP 3391 passes both ways, and you're looking at the right gateway | Slow or HTTP-only sessions; RD Gateway Manager shows no connections |
| 10. Change | Only after Steps 1-9 agree: one link, one change | Role reinstalled, same failure, and the policies are gone |
Step 1: Capture the symptom (read-only)
Write these on the ticket first:
| Fact | Why it matters |
|---|---|
| Which user and which client | One user, one group, everyone; a managed laptop, a home PC, a Mac, a web (RD Web) launch. Home PCs don't trust an internal CA (Step 3) and aren't in AD groups a CAP may require (Step 5) |
| Which network | Outside, inside, on VPN. Inside may bypass the gateway (Step 2) |
| Which gateway name | The exact FQDN in the client or the .rdp file, and the target name typed (short name, FQDN, or IP; Step 6) |
| Exact message and when it appears | Before the password prompt (name, 443, certificate), after the password (CAP, NPS, MFA), or after a pause with the session starting (RAP, target) |
| Since when, and what changed | A certificate renewal, a firewall or ISP change, a new public IP, an MFA rollout, a new NPS server, a Windows update |
| Time of one failing attempt | So you can match it to events 200-304 on the gateway and 6272/6273 on NPS |
Then branch on what you see:
| What you see | What it usually means (our reading unless noted) | Start at |
|---|---|---|
| Everyone outside fails, everyone inside works | The public path (DNS, NAT, edge firewall) or internal clients bypassing the gateway | Step 2 |
| A certificate expired, untrusted, or name mismatch warning | The certificate served on 443, not necessarily the one you imported | Step 3 |
| Only personal or home devices fail | The CA isn't trusted there, revocation can't be checked from the internet, or a CAP requires a domain computer group | Steps 3 and 5 |
| Everyone fails, inside through the gateway too | The gateway service, its listener, or its certificate binding | Steps 3 and 4 |
| Fails right after the password, event 201 on the gateway | CAP (or the central NPS policy when CAPs are central) | Steps 5 and 7 |
| Fails by short name, works by FQDN, event 301 | RAP resource list | Step 6 |
| No MFA prompt, or "temporarily unavailable" after the password while MFA is on | RADIUS timeout, the user's MFA method, or the NPS extension | Step 7 |
| Event 300 then 304, or the session host shows its own error | The target or the path from the gateway to it | Step 8 |
| Sessions work but feel slow, or RD Gateway Manager shows nothing | UDP 3391, or the wrong server or no gateway use at all | Step 9 |
Step 2: Does the public name reach the gateway on TCP 443? (read-only)
Microsoft's role page sets the public requirement: "The RD Gateway virtual machine must be accessible through a public IP address that allows inbound TCP connections to port 443 and inbound UDP connections to port 3391." Test it from where the users are, not from your desk. On an outside PC (a home connection or a phone hotspot):
# Read-only. From an OUTSIDE client: where does the public name point, and does TCP 443 answer? (name is an example)
Resolve-DnsName -Name rdg.contoso.com -Type A
Test-NetConnection -ComputerName rdg.contoso.com -Port 443
Then read what the deployment tells clients, on the RD Connection Broker (deployments managed from Server Manager):
# Read-only. On the RD Connection Broker: gateway mode, logon method, and the external FQDN handed to clients
Get-RDDeploymentGatewayConfiguration
Its documented output is Gatewaymode (Automatic, DoNotUse, or Custom), LogonMethod, and GatewayExternalFQDN. The matching Set- cmdlet also has -BypassLocal, which "Indicates whether authorized remote users bypass the RD Gateway server for local connections." With that on, an inside test can succeed without ever touching the gateway (our reading), so "it works from the office" is not a gateway test.
| Finding | What it means (our reading unless noted) | Next |
|---|---|---|
| The public name resolves to an old address, or not at all from outside | The public DNS record wasn't updated after an ISP or firewall change | Fix the public record (Step 10) |
| The name resolves correctly, TCP 443 fails from outside, works inside to the gateway's internal address | The edge firewall, NAT rule, or port forward | Fix the edge rule (Step 10) |
| TCP 443 answers, but Step 3 shows a certificate that isn't the gateway's | The forward lands on another server or a reverse proxy | Step 3, then the edge rule |
GatewayExternalFQDN differs from the public DNS name or the certificate name |
RD Web launches hand clients a name that won't match | Step 3; fix with Set-RDDeploymentGatewayConfiguration (Step 10) |
Gatewaymode is DoNotUse |
RD Web launches don't use the gateway at all; outside clients try 3389 directly | Step 10 |
| Everything here passes | The path is fine | Step 3 |
Test-NetConnection -Port only proves TCP: its -Port parameter "Specifies the TCP port number on the remote computer." UDP 3391 needs a different test (Step 9).
Step 3: Is the certificate it serves the right one, trusted, current, and checkable? (read-only)
This is where most "it broke after the renewal" tickets end. The client checks the certificate the gateway serves on 443, not the one you imported last week. Microsoft's requirements for the gateway certificate (from the original TS Gateway guidance, still the clearest list): "The name in the Subject line of the server certificate (certificate name, or CN) must match the DNS name that the client uses to connect to the TS Gateway server, unless you are using wildcard certificates or the SAN attributes of certificates.", "The certificate has not expired.", and "The certificate must be trusted on clients." The current RDS certificates page adds the usage: "Issued for Server Authentication (EKU 1.3.6.1.5.5.7.3.1)."
On the RD Gateway, compare the binding, the gateway's own setting, and the store:
# Read-only. On the RD Gateway: every HTTP.sys SSL binding (look at the :443 entries and their certificate hash)
netsh http show sslcert
# The certificate hash the RD Gateway service uses (CertHash), as a thumbprint string (our form)
$gw = Get-CimInstance -Namespace root/CIMV2/TerminalServices -ClassName Win32_TSGatewayServerSettings
$thumb = ($gw.CertHash | ForEach-Object { $_.ToString('X2') }) -join ''
$thumb
# Server authentication certificates in the computer store: names, expiry, thumbprints
Get-ChildItem -Path Cert:\LocalMachine\My -SSLServerAuthentication |
Select-Object Subject, DnsNameList, NotAfter, Thumbprint, Issuer | Format-List
# Does the certificate the gateway uses pass SSL policy for the public name? (name is an example)
Test-Certificate -Cert "Cert:\LocalMachine\My\$thumb" -Policy SSL -DNSName rdg.contoso.com
netsh http show sslcert "Lists SSL server certificate bindings along with their associated client certificate policies." CertHash "Specifies the certificate hash for HTTPS binding on port 443 in IIS." Test-Certificate -DNSName "Specifies the DNS name to verify as valid for the certificate." In a deployment managed from Server Manager, read what the deployment thinks too:
# Read-only. On the RD Connection Broker: the certificate assigned to the RD Gateway role
Get-RDCertificate -Role RDGateway | Format-List Subject, SubjectAlternateName, IssuedBy, ExpiresOn, Thumbprint, Level
Test-Certificate runs on the gateway, which trusts your internal CA and can reach your internal CRLs. A home PC can't. So check one failing outside client as well: export the gateway certificate's public part (.cer, no private key) and run Microsoft's chain check there:
:: Read-only. On a failing OUTSIDE client, with the exported gateway certificate (file name is an example)
certutil -urlfetch -verify rdg.cer
-urlfetch is documented as "Retrieve and verify AIA Certs and CDP CRLs." So it shows whether that client can build the chain and download the CRL from where it sits.
| Finding | What it means (Microsoft unless noted) | Next |
|---|---|---|
The netsh hash for :443 or $thumb isn't the new certificate's thumbprint |
The renewal imported a certificate, but the gateway still binds and serves the old one (our reading) | Bind the new one (Step 10) |
NotAfter or ExpiresOn is in the past |
Expired; clients refuse it | Replace it (Step 10) |
Test-Certificate -DNSName returns False |
The name clients use isn't in the subject or SAN. "The name of the certificate must match the FQDN used to access RD Gateway, whether the FQDN is the public IP address' externally facing DNS name or the CNAME DNS record pointing to the public IP address." | A certificate with the right name, or the right name in DNS and the client |
Level is Untrusted |
"The role service is configured with a self-signed certificate." Outside clients won't trust it | A publicly trusted certificate (Step 10) |
certutil chain fails on a home PC, passes on a domain PC |
A private CA. Microsoft: "If you use a privately issued certificate, you'll need to make sure to configure all clients with the certificate's trust chain beforehand." | A public certificate for the gateway, or deploy the root to those clients |
certutil builds the chain but can't fetch the CRL from outside |
The CDP is only reachable inside, so outside clients can't check revocation (our reading); Revocation Server Was Offline 0x80092013 covers CDP reachability | Publish the CRL where outside clients can reach it |
SslBridging (Step 4) is 1 or 2 |
A device in front terminates TLS (values: "HTTPS to HTTP bridging." and "HTTPS to HTTPS bridging."), so clients see the proxy's certificate (our reading) | Check the certificate on the proxy |
| All pass on the gateway and on an outside client | The certificate is fine | Step 4 |
Step 4: Is the gateway service healthy and listening? (read-only)
# Read-only. On the RD Gateway: the gateway service and the local NPS service it uses
Get-Service -Name TSGateway, IAS
# Listeners: TCP 443 (HTTPS) and UDP 3391 (RDP over UDP)
Get-NetTCPConnection -LocalPort 443 -State Listen
Get-NetUDPEndpoint -LocalPort 3391 -ErrorAction SilentlyContinue
# Gateway settings from its WMI provider (namespace Root\CIMv2\TerminalServices)
$gw = Get-CimInstance -Namespace root/CIMV2/TerminalServices -ClassName Win32_TSGatewayServerSettings
$gw | Select-Object IsConfigured, CentralCAPEnabled, MaxConnections, UnlimitedConnections, SslBridging, EnforceChannelBinding
# Read-only. Which transports are enabled and where they listen: 0 = RPC over HTTP, 1 = HTTP, 2 = UDP (our form)
foreach ($t in 0, 1, 2) {
$on = Invoke-CimMethod -InputObject $gw -MethodName IsTransportEnabled -Arguments @{ TransportType = [uint16]$t }
$ep = Invoke-CimMethod -InputObject $gw -MethodName GetIPAndPort -Arguments @{ TransportType = [uint16]$t }
[pscustomobject]@{ Transport = $t; Enabled = $on.Enabled; IPAddress = $ep.IPAddress; Port = $ep.Port }
}
# Errors and warnings in the gateway log, last two days
Get-WinEvent -FilterHashtable @{ LogName = 'Microsoft-Windows-TerminalServices-Gateway/Operational'; Level = 2, 3; StartTime = (Get-Date).AddDays(-2) } -MaxEvents 30 -ErrorAction SilentlyContinue |
Select-Object TimeCreated, Id, Message | Format-List
The RD Gateway WMI classes need an elevated session: "You must be a member of the Administrators group to use this class." The NPS service shows up as IAS (Microsoft's NPS extension guide says to "Restart the Network Policy Server (IAS) service."), and it's on the gateway by design: "By default, the role is already present on the computer configured as the Remote Desktop Gateway."
| Finding | What it means (Microsoft unless noted) | Next |
|---|---|---|
| TSGateway is stopped | Every connection fails at once | Start it, then read the gateway log for why it stopped |
Nothing listening on 443, or IsConfigured False |
IsConfigured "Specifies if IIS and RPC settings required by the RD Gateway service are configured." |
The IIS site or binding (Step 3 for the certificate), then Step 10 |
| The HTTP transport port isn't 443 | The port was changed: per Microsoft's ports page, TCP 443 "can be configured using the RD Gateway Management console." Clients and the edge rule must use the same port (our reading) | Match the client, the edge rule, and the gateway |
UnlimitedConnections False and MaxConnections low |
New connections are refused at the limit. MaxConnections "Returns the maximum number of connections that are allowed through RD Gateway." |
Raise it on purpose (Step 10) |
CentralCAPEnabled True |
"Specifies whether central RD CAP servers are used for controlling this server." The CAP decision is made by the central NPS, so editing local CAPs changes nothing (our reading) | Steps 5 and 7 |
| Gateway log errors at the time of the failures | The message names the failing part (certificate, service, authorization) | Map it back to Steps 3-8 |
| All healthy | The gateway is up | Step 5 |
Step 5: Does the user pass a connection authorization policy (CAP)? (read-only)
The gateway logs every authorization decision. Microsoft's RD Gateway guide reads the success events with Get-WinEvent on Microsoft-Windows-TerminalServices-Gateway/Operational; read the failures the same way, for one user, around the failure time:
# Read-only. On the RD Gateway: CAP, RAP, and connection events for one user, last 4 hours (user name is an example)
Get-WinEvent -FilterHashtable @{ LogName = 'Microsoft-Windows-TerminalServices-Gateway/Operational'; Id = 200, 201, 300, 301, 302, 303, 304; StartTime = (Get-Date).AddHours(-4) } -ErrorAction SilentlyContinue |
Where-Object { $_.Message -like '*jsmith*' } |
Select-Object TimeCreated, Id, Message | Format-List
Microsoft's event table for the gateway (written for TS Gateway, same IDs): 200 "Successful Connection Authorization", 201 "Failed Connection Authorization", 300 "Successful Resource Authorization", 301 "Failed Resource Authorization", 302 "Successful User Connection to the Resource", 303 when the client disconnects, 202 when an administrator disconnects it, and 304 "Failed User Connection to the Resource". A good attempt reads 200, 300, 302 in that order.
Then read the local CAPs in the order the gateway evaluates them:
# Read-only. On the RD Gateway: local CAPs, in evaluation order
Get-CimInstance -Namespace root/CIMV2/TerminalServices -ClassName Win32_TSGatewayConnectionAuthorizationPolicy |
Sort-Object Order |
Select-Object Order, Name, Enabled, UserGroupNames, ComputerGroupNames, PasswordAllowed, SmartcardAllowed, DeviceRedirectionType, AllowOnlySDRServers | Format-List
| Finding | What it means (Microsoft unless noted) | Next |
|---|---|---|
| Event 201 for the user | "The remote client could not connect to a TS Gateway server because the client did not meet the conditions specified in the TS CAPs." Read the message for the reason, then compare the user's groups with UserGroupNames
|
Step 10 (group membership, not a wider CAP) |
| No 200 or 201 at all for the attempt | The request never reached authorization (our reading) | Steps 2-4, or the RADIUS timeout in Step 7 |
ComputerGroupNames is set on the only matching CAP |
"If a value is specified, then the client computer must belong to one of these computer groups for the user to access the RD Gateway server." Home and personal PCs fail by design | Decide whether those devices should connect at all |
PasswordAllowed False, users sign in with a password |
PasswordAllowed "Indicates if a password can be used to connect to the RD Gateway server." |
Match the CAP to how users sign in |
The CAP you expect has Enabled False |
Enabled "Indicates whether this RD CAP will be used to evaluate a user for authorization." |
Find out who disabled it before you enable it |
AllowOnlySDRServers True and only some targets fail later |
AllowOnlySDRServers "Indicates whether connections allowed only to secure device redirection (SDR) RDS servers." Targets that don't enforce it are refused (our reading) |
Step 8 for those targets |
CentralCAPEnabled True (Step 4) |
This list isn't what decides; the central NPS network policy is | Step 7 |
| Event 200 for the user | The CAP passed | Step 6 |
Step 6: Does the target pass a resource authorization policy (RAP)? (read-only)
RAPs always live on the gateway itself: "RD RAPs can't use a central policy, as they're processed on the RD Gateway." Read them, and the resource groups they point at:
# Read-only. On EACH RD Gateway: RAPs and the resource groups behind them
Get-CimInstance -Namespace root/CIMV2/TerminalServices -ClassName Win32_TSGatewayResourceAuthorizationPolicy |
Select-Object Name, Enabled, UserGroupNames, ResourceGroupType, ResourceGroupName, PortNumbers | Format-List
Get-CimInstance -Namespace root/CIMV2/TerminalServices -ClassName Win32_TSGatewayResourceGroup |
Select-Object Name, AssociatedRAPs, Resources | Format-List
ResourceGroupType is RG (a gateway-managed group, listed in Win32_TSGatewayResourceGroup), CG (an Active Directory computer group), or ALL. Resources is a "Semicolon-separated list of resources in this resource group."
| Finding | What it means (Microsoft unless noted) | Next |
|---|---|---|
| Event 301, the user typed a short name, the resource group lists FQDNs | Microsoft's own example: "this issue might occur if the user attempts to connect to the computer by using its NetBIOS name when the TS RAP configured on the TS Gateway server uses an FQDN name for the computer." | Add the name users type, or have them use the FQDN (Step 10) |
ResourceGroupType CG, the target isn't in that AD computer group |
The RAP doesn't cover it | Add the computer to the group (Step 10) |
The target listens on a non-default port that isn't in PortNumbers
|
PortNumbers is a "List of semicolon-separated port numbers that are allowed for this policy." |
Add the port to that RAP (Step 10) |
The user passes the CAP but isn't in the RAP's UserGroupNames
|
A RAP has its own user groups, separate from the CAP (our reading) | Step 10 |
| Works through one gateway in a farm, fails through another | The RAPs differ between servers, since each gateway processes its own (our reading) | Compare this output on every gateway |
| Event 300 for the user and target | The RAP passed | Step 8 |
Step 7: Do NPS and the MFA extension answer in time? (read-only)
Skip this step if CentralCAPEnabled is False and no MFA is in the path. With a central NPS (the usual MFA design), the gateway is a RADIUS client: "Acting as a RADIUS client, the Remote Desktop Gateway server converts the request to a RADIUS Access-Request message and sends the message to the RADIUS (NPS) server where the NPS extension is installed." Read which NPS servers it uses:
# Read-only. On the RD Gateway: central NPS servers and their order (the class also exposes SharedSecret; don't select it)
Get-CimInstance -Namespace root/CIMV2/TerminalServices -ClassName Win32_TSGatewayRADIUSServer | Select-Object Name, Priority
Priority matters: "The RD Gateway server looks for RD CAPs on RADIUS servers based on the priority." Then open the NPS console on the gateway and read the timeout Microsoft tells you to change: NPS (Local) → RADIUS Clients and Servers → Remote RADIUS Server → TS GATEWAY SERVER GROUP → the server → Edit → Load Balancing. Microsoft: "change the default value from 3 to a value between 30 and 60 seconds". Three seconds isn't enough for a person to find a phone and approve a push.
On the NPS server where the extension is installed:
# Read-only. On the central NPS server: NPS decisions (6272 granted, 6273 denied) for the last 4 hours
Get-WinEvent -FilterHashtable @{ LogName = 'Security'; Id = 6272, 6273; StartTime = (Get-Date).AddHours(-4) } -MaxEvents 40 -ErrorAction SilentlyContinue |
Select-Object TimeCreated, Id, Message | Format-List
# The NPS extension's own logs (AzureMfa): list them, then read the channels it shows (our form)
Get-WinEvent -ListLog '*AzureMfa*' -ErrorAction SilentlyContinue | Select-Object LogName, RecordCount
# Can this server reach the MFA endpoints on TCP 443?
Test-NetConnection -ComputerName login.microsoftonline.com -Port 443
Test-NetConnection -ComputerName strongauthenticationservice.auth.microsoft.com -Port 443
Test-NetConnection -ComputerName adnotifications.windowsazure.com -Port 443
:: Read-only. On the NPS server: is NPS auditing on? (Microsoft's form)
auditpol /get /subcategory:"Network Policy Server"
Microsoft's NPS checklist says to look for 6273 or 6274: "Most authentication failures produce these events." The extension's logs are under Applications and Services Logs → Microsoft → AzureMfa, and the endpoints come from the extension's network requirements: "The NPS server must be able to communicate with the following URLs over TCP port 443:".
| Finding | What it means (Microsoft unless noted) | Next |
|---|---|---|
| The push arrives, but the connection has already failed, or only instant approvals work | The gateway's RADIUS timeout is still the default 3 seconds (our reading of Microsoft's instruction to raise it) | Step 10 (30-60 seconds) |
| The user only has SMS or a code registered | "The SMS text method doesn't work with Remote Desktop Gateway because it doesn't provide the option to enter a verification code." | Register phone call or Authenticator push |
| The user has a TOTP code and push registered, and fails | "If your organization uses Remote Desktop Gateway and the user registered for a TOTP code along with Authenticator push notifications, the user can't meet the Microsoft Entra MFA challenge and Remote Desktop Gateway sign-in fails." | Step 10 (Microsoft's registry override) |
| The extension is installed on the gateway itself, or the AzureMfa log shows REQUEST_FORMAT_ERROR | "Don't install the NPS extension on your Remote Desktop Gateway (RDG) server." and "NPS servers that are installed as dependencies for services like RDG and RRAS don't receive radius requests." | Move it to a separate NPS server (Step 10) |
| No 6272 or 6273 on the NPS server for the attempt, and an NPS event 13 | "A RADIUS message was received from the invalid RADIUS client IP address", so the gateway isn't a RADIUS client there | Add the gateway as a RADIUS client (Step 10) |
| NPS event 18 | "The NPS event log records this event when authentication fails because the shared secret key of the radius client doesn't match the shared secret key of the NPS server." | Reset the secret on both sides (Step 10) |
| 6273 on the NPS server | Read the reason code; NPS Event 6273 Reason Code 16 or 22 maps them. Microsoft's RD Gateway guide: "Ensure that your new policy is at the top of the list, that the policy is enabled, and that it grants access." | Fix the network policy order or conditions |
| AzureMfa log: AccessReject | "This error usually reflects an authentication failure in AD or that the NPS server is unable to receive responses from Microsoft Entra ID." | The AD account first, then the endpoints above |
| AzureMfa log: InvalidSession | "The session has taken more than three minutes to complete." | The user's response time, or latency on the path |
A Test-NetConnection above fails |
Outbound 443 from the NPS server is blocked or proxied | Allow the endpoints from that server |
| Prompts are sent, but users never see them | The phone side; Microsoft Authenticator Not Receiving Notifications covers it | That post |
Discarded duplicate requests in the NPS log are expected while a user is still answering the prompt: "Discarded requests in the NPS server event log don't indicate there's a problem with the NPS server or the Microsoft Entra multifactor authentication NPS extension."
Step 8: Can the gateway reach the target, and does the target accept the user? (read-only)
Once events 200 and 300 are logged, the gateway's job is to open RDP to the target from inside. Microsoft's ports page lists that leg: "TCP and UDP 3389: Used by RDP." From the gateway:
# Read-only. From the RD Gateway: does the target resolve, and does it answer on 3389, by the name users type? (names are examples)
Resolve-DnsName -Name app01.contoso.com -Type A
Test-NetConnection -ComputerName app01.contoso.com -Port 3389
| Finding | What it means (Microsoft unless noted) | Next |
|---|---|---|
| Event 304 | "The remote client met the conditions specified in the TS CAP and the TS RAP, but could not connect to the internal network resource (computer) through the TS Gateway server because the remote computer was unavailable." | The tests above, then the target |
| The name doesn't resolve from the gateway | The gateway needs internal DNS: "TCP and UDP 53: Used by the Domain Name System (DNS) for internal resource name resolution." | The gateway's DNS client settings |
| 3389 fails from the gateway, works from a PC on the same subnet as the target | A firewall between the gateway's subnet and the target (our reading) | Allow 3389 from the gateway |
| 3389 fails from everywhere | The target's RDP listener or service. Microsoft: "On both the local (client) computer and the remote (target) computer, the RDP listener should be listening on port 3389." | The target |
| Event 302 then 303 within seconds | The session reached the target and ended there (our reading); a licensing message points at Remote Desktop Licensing Mode Is Not Configured | The session host's own logs |
| "Access is denied" after the session starts | "This error usually indicates that the user who is trying to connect doesn't have the necessary permission to access the remote server." For a domain controller target: "Only members of the Domain Admins group can use RDP to connect to a domain controller." | Remote Desktop Users or the collection's user groups |
| "Account restriction is preventing this user from signing in" | Credential Guard: "It's not supported for connections that use RD Connection Broker or RD Gateway." | Microsoft's linked Credential Guard guidance |
Step 9: Is UDP 3391 working, and why is RD Gateway Manager empty? (read-only)
Read the live connections on the gateway. This is the same kind of list RD Gateway Manager's Monitoring node shows (our reading):
# Read-only. On EACH RD Gateway: live connections and their transport (0 = RPC over HTTP, 1 = HTTP, 2 = UDP)
Get-CimInstance -Namespace root/CIMV2/TerminalServices -ClassName Win32_TSGatewayConnection |
Select-Object UserName, ClientAddress, ConnectedResource, ConnectedPort, TransportProtocol, ConnectedTime, ConnectionDuration | Format-Table -AutoSize
UDP is the second transport: "UDP 3391: Used for RDP over UDP." Microsoft also notes that firewalls doing directional UDP analysis need the UDP rule set to Send Receive. Step 4 already showed whether transport 2 is enabled and listening.
| Finding | What it means (Microsoft unless noted) | Next |
|---|---|---|
UDP enabled and listening on 3391, every live connection shows TransportProtocol 1 |
UDP isn't making it through the edge or a load balancer, and sessions run on HTTP only (our reading) | Allow UDP 3391 both ways (Step 10) |
| A load balancer in front, HTTPS rule only | Microsoft's high-availability steps create a separate UDP rule for 3391 next to the 443 rule | Add the UDP rule |
| Some connections show 2 | UDP works for those clients | Compare client networks |
| Nothing listed here or in Monitoring, but users say they're connected | They aren't going through this gateway: another server in the farm, Gatewaymode DoNotUse, or local bypass (Step 2) (our reading) |
Run this on every gateway, then Step 2 |
| Monitoring was open before the user connected | It doesn't update on its own. Microsoft: "To refresh the display of connection status, in the Actions pane, click Refresh." | Refresh |
ClientAddress is the same address for everyone |
"If your network configuration includes proxy servers, the IP address that appears in this column will reflect the IP address of the proxy server, rather than the IP address of the Terminal Services client." | Expected behind a proxy or NAT |
| Connections show here, but no 200/300/302 events | Those events aren't being logged. In RD Gateway Manager, the server's Properties → Auditing tab is where "you can specify the types of events that you want to monitor" (Microsoft's TS Gateway wording) | Turn the event types back on |
Common false starts
| What people try | Why it misleads (our reading unless noted) |
|---|---|
| Reinstalling the RD Gateway role | It removes the CAPs, RAPs, resource groups, NPS settings, and certificate binding you needed to read, and the cause (a name, a certificate, a policy, a firewall) is usually still there |
| Testing from inside the office | Inside clients may resolve a different address or bypass the gateway (Step 2) |
| Importing the renewed certificate and stopping there | The gateway may still bind and serve the old one; compare CertHash, netsh http show sslcert, and the thumbprint (Step 3) |
| Turning off the Windows Firewall on the gateway | The edge firewall or NAT in front is the usual block for outside users; this opens the server and proves little |
| Changing the CAP and RAP to allow everyone to everything | The gateway becomes an open path from the internet to every internal computer; events 201 and 301 already say which policy and which name failed |
| Uninstalling the NPS extension | MFA is gone, and if CAPs are central the RADIUS timeout or method problem is still there (Step 7) |
| Installing the NPS extension on the gateway | Microsoft: "Don't install the NPS extension on your Remote Desktop Gateway (RDG) server." |
Test-NetConnection to 3391 |
It tests TCP only; 3391 is UDP |
| Blaming UDP for a connection that never starts | UDP is a second transport; a session that never starts is usually Steps 2-8 (our reading) |
| Restarting TSGateway as the fix | It can clear a stuck state, and it also hides which link failed; read the log first |
Step 10: Change one link, then prove it
Only after Steps 1-9 agree on which link failed. Save the gateway's configuration first. The Export method "Returns the Remote Desktop Gateway (RD Gateway) server configuration as an XML string.", and its export bits add up to everything that matters here:
# Read-only, but store the file like a secret. On EACH RD Gateway: export CAPs (1), RADIUS servers (2), RAPs (4), resource groups (8), load-balancing servers (16), and server settings (32) = 63 (our form; path is an example)
$srv = Get-CimInstance -Namespace root/CIMV2/TerminalServices -ClassName Win32_TSGatewayServer
$out = Invoke-CimMethod -InputObject $srv -MethodName Export -Arguments @{ ExportType = [uint32]63 }
$out.XmlString | Out-File -FilePath C:\Temp\rdg-before.xml -Encoding utf8
Keep the Step 3 thumbprints, the Step 5 and 6 policy output, and the NPS timeout values with it (our habit).
The public name or the edge (Step 2). Fix the public DNS record, or the edge rule and NAT to the gateway: TCP 443 inbound, and UDP 3391 if you use UDP, with the UDP rule allowing both directions. If RD Web launches hand out the wrong name, set it on the RD Connection Broker (names are examples):
# Change. On the RD Connection Broker: the external gateway name clients get from the deployment
Set-RDDeploymentGatewayConfiguration -GatewayMode Custom -GatewayExternalFqdn rdg.contoso.com -LogonMethod Password -UseCachedCredentials $true -BypassLocal $false -ConnectionBroker rdcb.contoso.com
Custom means "Remote users get Gateway settings from other parameters to this cmdlet." Setting -BypassLocal $false also makes inside tests go through the gateway, which you want while you troubleshoot (our reading).
The certificate (Step 3). Get a certificate whose name matches the public FQDN, with Server Authentication, from a CA your outside clients trust (Microsoft recommends public for the gateway: "Because the RD Gateway role is supposed to be public, we recommend you use a publicly issued certificate."). In a deployment, assign it to the RD Gateway role on the RD Connection Broker with Microsoft's form:
# Change. On the RD Connection Broker: assign the PFX to the RD Gateway role (Microsoft's form with Role RDGateway; path is an example)
$password = Read-Host -AsSecureString -Prompt "Enter Password"
Set-RDCertificate -Role RDGateway -ImportPath 'C:\Certs\rdg-2026.pfx' -Password $password -ConnectionBroker rdcb.contoso.com
On Windows Server 2019 and later, -Thumbprint can point at a certificate that's already installed ("The parameter is available on Windows Server 2019 and later."). For a standalone gateway, use RD Gateway Manager: the server's Properties → SSL Certificate → Import a certificate into the RD Gateway → Browse and Import Certificate. Microsoft's high-availability steps add a note worth keeping: "You may need to manually restart the TSGateway service running on each RD Gateway server, either through Server Manager or Task Manager." Then rerun Step 3 on the gateway and on an outside client. If outside clients can't reach your CRL, publish it where they can before you move on.
The service or limits (Step 4). Start TSGateway and read why it stopped. Raise MaxConnections only if the limit, not an attack, was the cause (in RD Gateway Manager, server Properties).
The CAP (Step 5). Add the user to the group the CAP already names, or add the right group to that CAP in RD Gateway Manager (Policies → Connection Authorization Policies). Don't widen it to Domain Users or remove the computer group condition unless you've decided those devices should connect.
The RAP (Step 6). Add the name users actually type (short name and FQDN) to the RD Gateway-managed computer group, or the computer to the AD group the RAP uses, or the custom port to the RAP. Do it on every gateway in the farm.
NPS and MFA (Step 7). Raise the gateway's RADIUS timeout to 30-60 seconds on the Load Balancing tab, and set "Number of seconds between requests when server is identified as unavailable" to the same or more (Microsoft's step). If the NPS server doesn't know the gateway, add it as a RADIUS client with the same shared secret; if event 18 shows a secret mismatch, set a new long secret on both sides. If the NPS server isn't registered, Microsoft's step is Register server in Active Directory: "To function properly in this scenario, the NPS server needs to be registered in Active Directory." For users with both TOTP and push registered, Microsoft's fix is a registry value under HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\AzureMfa on the NPS extension server, then an NPS service restart:
# Change. On the NPS EXTENSION server (not the gateway): fall back to Approve/Deny for RD Gateway (Microsoft's value, string FALSE)
New-ItemProperty -Path 'HKLM:\SOFTWARE\Microsoft\AzureMfa' -Name OVERRIDE_NUMBER_MATCHING_WITH_OTP -Value 'FALSE' -PropertyType String -Force
Restart-Service -Name IAS
Microsoft's wording: "set OVERRIDE_NUMBER_MATCHING_WITH_OTP = FALSE to fall back to Approve/Deny push notifications with Authenticator." If the extension sits on the gateway, install it on a separate NPS server and point the gateway's central CAP store there, following Microsoft's RD Gateway integration steps, instead of patching it in place.
The target (Step 8). Fix the firewall from the gateway to the target, the target's RDP listener, or the user's rights on the target. Nothing on the gateway changes.
UDP (Step 9). Allow UDP 3391 both ways at the edge and on any load balancer. If you can't yet, sessions keep working over HTTP; leave UDP enabled on the gateway so it starts working when the edge is fixed (our reading).
Then prove it. From an outside client, as the user who failed: the connection succeeds, the gateway log shows 200, 300, and 302 for that user at that time, Win32_TSGatewayConnection lists the session (with TransportProtocol 2 if UDP should work), Test-Certificate -DNSName returns True for the public name, and NPS logs 6272 when MFA is in the path (our reading). Then have the helpdesk retest the original users.
When a change is justified
| Finding | Prefer | Avoid |
|---|---|---|
| Public name or edge rule wrong | Fix the record or the NAT and edge rule for 443 (and 3391 UDP) | Opening 3389 to the internet instead |
| Certificate old, expired, mismatched, or private | A public certificate with the right name, bound on every gateway | Telling users to click through the warning |
| CAP fails for a user | Add the user to the group the CAP names | A CAP for Domain Users with no other conditions |
| RAP fails by short name | Add the names users type, or teach the FQDN | A RAP that allows any resource |
| MFA times out | RADIUS timeout 30-60 seconds | Removing MFA or the NPS extension |
| TOTP plus push users fail | Microsoft's OVERRIDE_NUMBER_MATCHING_WITH_OTP = FALSE
|
Deleting the users' TOTP method without telling them |
| 304 to one target | The target or the firewall in front of it | Changing gateway policies |
| UDP never used | UDP 3391 open both ways on the edge and the load balancer | Disabling UDP on the gateway to make the symptom go away |
FAQ
Why is my RD Gateway not working externally when it works inside?
Usually the public name points somewhere else, the edge firewall or NAT doesn't pass TCP 443 to the gateway, or inside clients bypass the gateway so the inside test proves nothing. Microsoft requires "inbound TCP connections to port 443 and inbound UDP connections to port 3391" on the public address. Test Resolve-DnsName and Test-NetConnection -Port 443 from an outside network (Step 2).
What does "Remote Desktop Gateway server is temporarily unavailable" mean?
The client didn't get a usable answer from the gateway: the name, 443, the TLS handshake, the service, or (with MFA) a RADIUS timeout. For Windows 365 Boot, Microsoft says "This issue might be a transient issue because of network congestion.", but for your own gateway, read Steps 2-4 and 7 before you wait it out.
What ports does RD Gateway use?
From clients: TCP 443 for HTTPS and UDP 3391 for "RDP over UDP". From the gateway inward: 3389 to the targets, DNS, Kerberos and LDAP to AD, CRL ports, and "UDP 1812 and 1813: Required when Network Policy Server (NPS) is used."
How do I fix an expired RD Gateway certificate?
Get a new certificate with the public name and Server Authentication, assign it to the RD Gateway role (Set-RDCertificate -Role RDGateway, or RD Gateway Manager's SSL Certificate tab), restart TSGateway if needed, and confirm CertHash and netsh http show sslcert show the new thumbprint (Steps 3 and 10).
Why isn't RD Gateway MFA with the NPS extension prompting or working?
Most often the gateway's RADIUS timeout is still 3 seconds, the user only has SMS or a code (RD Gateway supports phone call and Authenticator Approve/Deny), the user has both TOTP and push registered, or the extension is installed on the gateway. Read the AzureMfa log and Security events 6272/6273 on the NPS server (Step 7).
Related posts
- NPS Event 6273 Reason Code 16 or 22 (when the central NPS denies the gateway's RADIUS request)
- Revocation Server Was Offline 0x80092013 (when outside clients can't check the gateway certificate's CRL)
- Microsoft Authenticator Not Receiving Notifications (when the MFA push is sent but never shows up)
- Remote Desktop Licensing Mode Is Not Configured (when the session host refuses users after the gateway lets them through)
- Certificate Autoenrollment Not Working (when an internal CA should be renewing the gateway or NPS certificates)
Free checklist
Reinstalling the gateway and opening every policy before anyone read events 201 and 301 is a change made everywhere at once. So is a Conditional Access policy enforced before anyone read the report-only results. The free Conditional Access pre-enforcement checklist keeps break-glass accounts, pilot groups, and report-only review on one page:
If you want the rest of the Intune runway written down for the team (enrollment hygiene, compliance phasing, break/fix cards and read-only PowerShell snapshots), the Intune & M365 Admin Starter Pack pairs with this triage: https://cashflow4375.gumroad.com/l/joonf?utm_source=devto&utm_medium=article&utm_campaign=aps_first_sale&utm_content=rd-gateway-not-working
Admin Pack Studio; not affiliated with Microsoft. Steps 1-9 favor read-only checks: Resolve-DnsName, Test-NetConnection, Get-RDDeploymentGatewayConfiguration, netsh http show sslcert, Get-ChildItem Cert:, Test-Certificate, Get-RDCertificate, certutil -urlfetch -verify, Get-Service, Get-NetTCPConnection, Get-NetUDPEndpoint, Get-CimInstance and read-only Invoke-CimMethod calls on the RD Gateway WMI classes, Get-WinEvent, and auditpol /get. Exporting the gateway configuration creates a sensitive file. Changing DNS, edge rules, certificates, gateway settings, CAPs, RAPs, resource groups, RADIUS timeouts or secrets, NPS registration, or the NPS extension registry, and restarting services, are deliberate changes. Change one link at a time, test from an outside client and from the gateway, and check current Microsoft Learn for version-specific behavior.
Top comments (0)