Server 2019 RDP Disconnects

Windows Server 2019 RDP Disconnects After Inactivity: Complete Troubleshooting Guide

Problem: An administrator connected to a Windows Server 2019 system by Remote Desktop was repeatedly disconnected after the session had been idle. The Remote Desktop client displayed a message stating that the session ended because the remote computer did not receive any input.

The final cause was not a TCP timeout, firewall timeout, VPN timeout, or the ordinary Group Policy setting alone. The RDP listener itself had a hard-coded three-hour idle limit stored under the WinStations\RDP-Tcp registry key.

Symptoms

The Remote Desktop client displayed a message similar to:

Your Remote Desktop Services session ended because the remote computer did not receive any input from you.

The Terminal Services event log also recorded:

Session 5 has been idle over its time limit, and was disconnected.

This confirmed that Windows Terminal Services itself was enforcing an idle-session limit.

Initial Group Policy Review

The first troubleshooting step was to inspect the normal Remote Desktop session timeout policies:

Computer Configuration
  Administrative Templates
    Windows Components
      Remote Desktop Services
        Remote Desktop Session Host
          Session Time Limits

The relevant policies were:

  • Set time limit for active but idle Remote Desktop Services sessions
  • Set time limit for disconnected sessions
  • Set time limit for active Remote Desktop Services sessions
  • End session when time limits are reached

The server was also a domain controller, so both local and domain Group Policy had to be considered.

Checking the Resultant Set of Policy

The following command showed which Group Policy Objects applied to the server:

gpresult /r

The server applied:

  • Default Domain Controllers Policy
  • Default Domain Policy
  • Local Group Policy

A more detailed report was also generated:

gpresult /h C:\gpresult.html

The server was found to have a three-hour idle timeout and an eight-hour disconnected-session timeout.

Inspecting the Policy Registry Values

The effective Remote Desktop policy registry key was queried:

reg query "HKLM\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services"

The important values were:

MaxIdleTime             REG_DWORD    0x00A4CB80
MaxDisconnectionTime    REG_DWORD    0x01B77400

These values are stored in milliseconds:

  • 0x00A4CB80 = 10,800,000 milliseconds = 3 hours
  • 0x01B77400 = 28,800,000 milliseconds = 8 hours

The three-hour value matched the observed behavior.

Finding the Domain Policy That Recreated the Timeout

The MaxIdleTime value was deleted temporarily:

reg delete "HKLM\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services" /v MaxIdleTime /f

After running:

gpupdate /force

the value returned. This proved that Group Policy was actively recreating it.

Inspection with gpmc.msc showed:

  • The Default Domain Controllers Policy did not configure the idle limit.
  • The Default Domain Policy configured the idle limit for three hours.

The Default Domain Policy setting was changed to Not Configured, Group Policy was refreshed, and the server was rebooted.

Afterward, the policy registry key no longer contained MaxIdleTime.

Checking for Other Idle-Timeout Mechanisms

Interactive Logon Inactivity Limit

The following policy was checked:

Computer Configuration
  Windows Settings
    Security Settings
      Local Policies
        Security Options
          Interactive logon: Machine inactivity limit

It was set to 0, meaning disabled.

RDP Session Type

The current session was confirmed to be a normal administrative RDP session:

qwinsta /server:localhost
query session

Legacy Terminal Server Registry Values

Because the disconnect persisted, the broader Terminal Server registry tree was searched:

reg query "HKLM\SYSTEM\CurrentControlSet\Control\Terminal Server" /s | findstr /i "Idle TimeOut Max"

This revealed another three-hour MaxIdleTime value outside the normal policy branch.

The Actual Root Cause

A PowerShell search identified the exact registry location:

Get-ChildItem "HKLM:\SYSTEM\CurrentControlSet\Control\Terminal Server" -Recurse |
ForEach-Object {
    try {
        $p = Get-ItemProperty $_.PSPath -ErrorAction Stop
        if ($null -ne $p.MaxIdleTime) {
            Write-Host ""
            Write-Host $_.Name
            $p | Select-Object MaxIdleTime,
                                 MaxConnectionTime,
                                 MaxDisconnectionTime,
                                 fInheritMaxIdleTime,
                                 fInheritMaxSessionTime,
                                 fInheritMaxDisconnectionTime
        }
    }
    catch {
        # Ignore protected registry keys that cannot be read.
    }
}

The offending values were found here:

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Terminal Server\WinStations\RDP-Tcp

The key contained:

MaxIdleTime          = 10800000
fInheritMaxIdleTime  = 0

This meant:

  • The RDP listener itself had a hard-coded three-hour timeout.
  • The listener was configured not to inherit the normal policy value.
  • Removing the Group Policy timeout alone was therefore not sufficient.

Backing Up the RDP Listener Configuration

Before making any registry changes, the RDP listener key was exported:

reg export "HKLM\SYSTEM\CurrentControlSet\Control\Terminal Server\WinStations\RDP-Tcp" C:\RDP-Tcp.reg

Final Fix

The RDP listener idle timeout was set to zero:

reg add "HKLM\SYSTEM\CurrentControlSet\Control\Terminal Server\WinStations\RDP-Tcp" /v MaxIdleTime /t REG_DWORD /d 0 /f

The listener was then configured to inherit the idle-time policy:

reg add "HKLM\SYSTEM\CurrentControlSet\Control\Terminal Server\WinStations\RDP-Tcp" /v fInheritMaxIdleTime /t REG_DWORD /d 1 /f

The server was rebooted so the Remote Desktop listener would reload its configuration.

Verification After Reboot

The values were verified with:

reg query "HKLM\SYSTEM\CurrentControlSet\Control\Terminal Server\WinStations\RDP-Tcp" /v MaxIdleTime

reg query "HKLM\SYSTEM\CurrentControlSet\Control\Terminal Server\WinStations\RDP-Tcp" /v fInheritMaxIdleTime

The expected results were:

MaxIdleTime            REG_DWORD    0x0
fInheritMaxIdleTime    REG_DWORD    0x1

After these changes, the RDP session remained connected beyond the previous three-hour idle limit.

Why the Problem Was Difficult to Diagnose

There were two independent timeout mechanisms involved:

  1. A three-hour idle timeout in the Default Domain Policy.
  2. A separate three-hour timeout stored directly in the RDP-Tcp listener configuration.

Changing Group Policy removed the policy-layer timeout, but the listener-level timeout remained active. The event log correctly reported that the session exceeded its idle time limit, but it did not identify which registry location supplied that limit.

Recommended Troubleshooting Sequence

  1. Record the exact RDP disconnect message and the approximate timeout interval.
  2. Check the Terminal Services event logs for an idle-time-limit event.
  3. Run gpresult /r and generate an HTML Group Policy report.
  4. Inspect HKLM\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services.
  5. Check both Local Group Policy and domain-linked GPOs with gpmc.msc.
  6. Verify that Interactive logon: Machine inactivity limit is not responsible.
  7. Confirm the session type with qwinsta or query session.
  8. Search the full Terminal Server registry tree for additional MaxIdleTime values.
  9. Inspect WinStations\RDP-Tcp.
  10. Back up the registry key before modifying listener-level RDP configuration.
  11. Reboot and verify the final effective settings.

Important Administrative Notes

  • Changing the Default Domain Policy can affect every computer in the domain.
  • For long-term management, use a dedicated GPO rather than placing unrelated Remote Desktop settings in the Default Domain Policy.
  • A disconnected-session limit is different from an active-but-idle limit.
  • MaxDisconnectionTime applies after a session has already been disconnected.
  • MaxIdleTime controls when an active but idle session is disconnected.
  • Always export the relevant registry key before changing listener-level RDP configuration.
  • On customer systems, confirm that any security or compliance policy allows idle sessions to remain connected indefinitely.

Final Configuration

Policy registry:
HKLM\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services
    MaxIdleTime = not present

RDP listener:
HKLM\SYSTEM\CurrentControlSet\Control\Terminal Server\WinStations\RDP-Tcp
    MaxIdleTime = 0
    fInheritMaxIdleTime = 1

This eliminated the hard-coded three-hour RDP idle disconnect.