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 hours0x01B77400= 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:
- A three-hour idle timeout in the Default Domain Policy.
- A separate three-hour timeout stored directly in the
RDP-Tcplistener 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
- Record the exact RDP disconnect message and the approximate timeout interval.
- Check the Terminal Services event logs for an idle-time-limit event.
- Run
gpresult /rand generate an HTML Group Policy report. - Inspect
HKLM\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services. - Check both Local Group Policy and domain-linked GPOs with
gpmc.msc. - Verify that Interactive logon: Machine inactivity limit is not responsible.
- Confirm the session type with
qwinstaorquery session. - Search the full Terminal Server registry tree for additional
MaxIdleTimevalues. - Inspect
WinStations\RDP-Tcp. - Back up the registry key before modifying listener-level RDP configuration.
- 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.
MaxDisconnectionTimeapplies after a session has already been disconnected.MaxIdleTimecontrols 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.