Windows Server  ·  high  ·  Exchange, WSUS, PKI & RDS

Remote Desktop Gateway refuses connections — event 4, 23003 and 23005

The gateway is refusing at the connection authorisation policy, the resource authorisation policy, or on the certificate.

What you see

Users cannot connect through the gateway, with a message about the gateway being unavailable or the credentials being refused. Internal connections work.

What is actually wrong

The user is not in a group the connection policy allows, the resource policy does not permit the target computer, or the certificate name does not match what clients use.

Codes and articles

Event 23003Event 23005Event 4RD Gateway0x800b0109 gatewayCAP RAP

Fixes (3)

Fix the connection authorisation policy
Elevated PowerShell on the gateway30 minutesmedium riskreversible

Event 23003.

  1. Read the event — it names the user and the policy that rejected them.

    PowerShell
    Get-WinEvent -LogName 'Microsoft-Windows-TerminalServices-Gateway/Operational' -MaxEvents 40 | Format-Table TimeCreated,Id,Message -Wrap
  2. List the connection policies and their groups.

    PowerShell
    Import-Module RemoteDesktopServicesGet-ChildItem RDS:\GatewayServer\CAP | Format-Table NameGet-ChildItem 'RDS:\GatewayServer\CAP\Default CAP\UserGroups'
  3. Add the required group. Groups must be specified in DOMAIN\Group form.

    PowerShell
    New-Item -Path 'RDS:\GatewayServer\CAP\Default CAP\UserGroups' -Name 'EXAMPLE\RemoteUsers' -ItemType String
  4. Check the device redirection and authentication method settings match what the client is offering — a policy requiring smart cards rejects a password logon here.

    PowerShell
    Get-ChildItem 'RDS:\GatewayServer\CAP\Default CAP' | Format-Table Name,CurrentValue

    The gateway evaluates the authentication method before anything else. A mismatch produces a rejection that reads as a credential failure, and the user will keep retyping a correct password.

  5. Restart the gateway service after policy changes.

    PowerShell
    Restart-Service TSGateway
Confirm it workedThe user connects and event 302 (connection authorised) is logged.
PowerShell
Get-WinEvent -LogName 'Microsoft-Windows-TerminalServices-Gateway/Operational' -MaxEvents 20 | Where-Object Id -in 300,302 | Format-Table TimeCreated,Id
If you need to undo itRemove the added group from the policy.
Fix the resource authorisation policy
Elevated PowerShell30 minutesmedium riskreversible

Event 23005 — the user is allowed in but not to that machine.

  1. List the resource policies and the computer groups they allow.

    PowerShell
    Get-ChildItem RDS:\GatewayServer\RAP | Format-Table NameGet-ChildItem 'RDS:\GatewayServer\RAP\Default RAP\ComputerGroupType'
  2. The computer must be named exactly as the client asks for it. A policy listing the NetBIOS name rejects a client that connects by fully qualified name.

    This is the most common resource policy fault and it is invisible unless you compare the two strings directly. The gateway does no name resolution to match them.

  3. Add the target to the allowed group, or use an Active Directory group of computers for maintainability.

    PowerShell
    Set-Item 'RDS:\GatewayServer\RAP\Default RAP\ComputerGroupType' -Value 1New-Item -Path 'RDS:\GatewayServer\RAP\Default RAP\ComputerGroup' -Name 'EXAMPLE\RDS-Hosts' -ItemType String
  4. Check the allowed ports — a policy restricted to 3389 blocks anything on a custom port.

    PowerShell
    Get-ChildItem 'RDS:\GatewayServer\RAP\Default RAP' | Format-Table Name,CurrentValue
  5. Restart the service and re-test.

    PowerShell
    Restart-Service TSGateway
Confirm it workedThe connection to the intended host succeeds through the gateway.
If you need to undo itRemove the added computer group entry.
Fix the gateway certificate
Elevated PowerShell40 minutesmedium riskreversible

A certificate error at the client.

  1. Check what is bound and whether it has expired.

    PowerShell
    Get-ChildItem Cert:\LocalMachine\My | Format-Table Subject,DnsNameList,NotAfter,Thumbprint -AutoSize
  2. The certificate's subject or a SAN entry must match the external name clients use, exactly. An internal name on a certificate presented externally always fails.

    Gateway certificates are one of the few places where an internal CA is usually the wrong choice — external clients have no reason to trust it, and a public certificate for the external name avoids the whole problem.

  3. Bind the correct certificate.

    PowerShell
    Set-Item 'RDS:\GatewayServer\SSLCertificate\SSLCertificateSHA1Hash' -Value 'ABCDEF1234567890...'Restart-Service TSGateway
  4. Confirm the full chain is served, not just the leaf. A missing intermediate works in a browser that has it cached and fails on a fresh client.

    PowerShell
    Test-NetConnection rdg.example.com -Port 443 -InformationLevel Detailed
  5. Check the certificate is also valid for the RD Web and connection broker roles if they share the name.

Confirm it workedA client on a machine that has never connected before succeeds without a certificate warning.
If you need to undo itRebind the previous certificate hash.

Where this stops. This write-up was written and checked by hand. It says what each step changes, how to confirm it worked and how to reverse it, and anything destructive is flagged before you reach it. If it does not match what your machine is doing, search the Support Centre for the exact code or message — and when something needs a person, get in touch.