// DevOps

Windows Server 2019: RDP stopped connecting, even though port 3389 is open. Troubleshooting and resolution of Event ID 1057

Published on 2026-07-08

Introduction

One unpleasant scenario on Windows Server is when Remote Desktop suddenly stops working, while from the outside everything looks “almost normal”:

  • port 3389 is open;
  • the Remote Desktop Services service is running;
  • the firewall is not blocking the connection;
  • qwinsta shows that rdp-tcp is listening;
  • but you cannot connect even as an administrator;
  • RemoteApp also does not work because the underlying RDP session is not created.

In my case the problem occurred on Windows Server 2019 with RDS/RemoteApp. At first it seemed that RemoteApp itself had broken, but diagnostics quickly showed: the problem is lower, at the RDP TLS / certificate / SChannel level.

Key symptom in the Event Viewer:

Event ID: 1057
Provider: Microsoft-Windows-TerminalServices-RemoteConnectionManager

The Remote Desktop Session Host server failed to create
a new self-signed certificate to be used to authenticate the
Remote Desktop Session Host server for SSL connections.

Status code: The specified algorithm is incorrect.

In this article we’ll cover:

  1. how to properly diagnose such a failure;
  2. how to understand that the port is open but RDP still doesn’t work;
  3. why disabling TLS temporarily restores access;
  4. how to restore normal RDP operation via a correct certificate;
  5. why you must not leave SecurityLayer = 0;
  6. what to check after recovery;
  7. how to restore RemoteApp/RDWeb after repairing the underlying RDP.

1. Symptoms

Initially the issue looked like this:

  • users cannot start RemoteApp;
  • a regular RDP connection also does not work;
  • not even the administrator can sign in;
  • port 3389 is open;
  • RDP services are running.

What the user sees on the client

From the client’s mstsc this failure looks different depending on the client version and connection settings. Most often it’s one of two messages.

The first variant — concise:

An internal error has occurred.

The second variant — with codes:

The remote session could not be connected to because the
timed out while trying to establish the connection, or an error occurred.

Error code: 0x904
Extended error code: 0x7

Both messages are the same problem seen from different sides. The client establishes a TCP connection to 3389, starts the TLS handshake — and the server drops the connection because it cannot present a certificate. The client doesn’t know why the server dropped the session, so it shows a generic “An internal error has occurred” or 0x904 / 0x7.

Important diagnostic takeaway: if the client shows “An internal error has occurred” or 0x904 / 0x7, you can stop trying to decode client-side codes. The real cause is on the server, and you need to look for it in the server’s Event Viewer, not on the client.

Service state on the server

On the server the services looked like this:

powershell
Get-Service TermService,SessionEnv,UmRdpService,W3SVC -ErrorAction SilentlyContinue |
Select-Object Name,DisplayName,Status,StartType

Example output:

Name         DisplayName                                                                     Status   StartType
----         -----------                                                                     ------   ---------
SessionEnv   Remote Desktop Configuration                                                     Running  Manual
TermService  Remote Desktop Services                                                         Running  Manual
UmRdpService Remote Desktop Services UserMode Port Redirector                              Running  Manual
W3SVC        World Wide Web Publishing Service                                              Stopped  Disabled

At this stage it’s important not to draw the wrong conclusion.

W3SVC is required for IIS and RD Web Access. If it is stopped, the RemoteApp web portal may be unavailable. But W3SVC itself should not break a normal mstsc to port 3389.

If even direct RDP doesn’t work, you must first fix the underlying RDP, and only then return to RemoteApp/RDWeb.


2. Important distinction: open port ≠ working RDP

A very common trap: an administrator checks port 3389, sees it is open, and assumes RDP should work.

For example:

powershell
Test-NetConnection server.example.com -Port 3389

Or from Linux/macOS:

bash
nc -vz server.example.com 3389

If the TCP port is open, that proves only one thing: you can establish a TCP connection to the server on 3389.

This does not prove that the following are working successfully:

  • RDP listener;
  • WinStation RDP-Tcp;
  • TLS handshake;
  • NLA;
  • CredSSP;
  • RDP certificate;
  • interactive logon rights;
  • RDS licensing;
  • RemoteApp collection.

In my case the port was open, but the TLS part of RDP was not working.


3. First layer of diagnostics: is the RDP listener listening

On the server you need to check the RDP sessions state:

cmd
qwinsta

or:

cmd
query session

In my case the output was like this:

SESSION           USERNAME                 ID  STATE   TYPE        DEVICE
services                                    0  Disc
>console           Administrator             1  Active
rdp-tcp                                 65536  Listen

The line:

rdp-tcp  65536  Listen

means that the RDP listener exists and is in a listening state.

You also need to check whether logons are disabled:

cmd
change logon /query

Normal output:

Session logons are currently ENABLED

If logons are disabled, enable them:

cmd
change logon /enable

4. Check if RDP is disabled in the registry

Basic RDP setting is stored here:

powershell
Get-ItemProperty 'HKLM:\SYSTEM\CurrentControlSet\Control\Terminal Server' |
Select-Object fDenyTSConnections

Normal value:

fDenyTSConnections : 0

If it’s 1, RDP is disabled:

powershell
Set-ItemProperty `
  -Path 'HKLM:\SYSTEM\CurrentControlSet\Control\Terminal Server' `
  -Name fDenyTSConnections `
  -Value 0

5. Check RDP-Tcp parameters

Next check the settings of the RDP listener itself:

powershell
$RdpTcp = 'HKLM:\SYSTEM\CurrentControlSet\Control\Terminal Server\WinStations\RDP-Tcp'

Get-ItemProperty $RdpTcp |
Select-Object `
  PortNumber,
  UserAuthentication,
  SecurityLayer,
  MinEncryptionLevel,
  fEnableWinStation,
  MaxInstanceCount,
  SSLCertificateSHA1Hash

In my case it was:

PortNumber             : 3389
UserAuthentication     : 0
SecurityLayer          : 2
MinEncryptionLevel     : 2
fEnableWinStation      : 1
MaxInstanceCount       : 4294967295
SSLCertificateSHA1Hash :

At first glance everything seems almost normal:

  • port 3389;
  • WinStation enabled;
  • maximum number of sessions not limited;
  • NLA disabled for diagnostics.

But there’s an important detail:

SecurityLayer : 2
SSLCertificateSHA1Hash : empty

SecurityLayer = 2 means RDP is supposed to use SSL/TLS. And empty SSLCertificateSHA1Hash means there is no explicit certificate binding.

Usually Windows can create a self-signed certificate for RDP on its own. But if certificate creation breaks, the TLS connection for RDP also breaks.


6. What SecurityLayer and UserAuthentication mean

For diagnostic understanding it’s important to know what the main parameters mean.

SecurityLayer

SecurityLayer = 0

Uses the old RDP Security Layer. This is an emergency and less secure mode. It can be used only temporarily for recovery.

SecurityLayer = 1

Negotiate. The client and server negotiate the available security level. Usually this is a practical and safe option for recovery.

SecurityLayer = 2

SSL/TLS only. The server requires TLS. If the TLS certificate or SChannel is broken, RDP may fail to connect completely.

UserAuthentication

UserAuthentication = 0

NLA is disabled.

UserAuthentication = 1

NLA is enabled.

NLA is desirable in production mode, but during diagnostics it can be disabled to separate authentication problems from transport/TLS problems.


7. Key check: temporarily disable TLS

To determine whether the problem is indeed TLS, you can temporarily switch RDP to emergency mode:

powershell
$RdpTcp = 'HKLM:\SYSTEM\CurrentControlSet\Control\Terminal Server\WinStations\RDP-Tcp'

Set-ItemProperty -Path $RdpTcp -Name UserAuthentication -Value 0
Set-ItemProperty -Path $RdpTcp -Name SecurityLayer -Value 0
Set-ItemProperty -Path $RdpTcp -Name MinEncryptionLevel -Value 1

Restart-Service TermService -Force

Note: Restart-Service TermService -Force will drop all active RDP sessions. In our scenario nobody could connect anyway, so there’s nothing to lose, but on a “half-alive” server this should be kept in mind.

After this check test the connection:

cmd
mstsc /admin /v:127.0.0.1

Or from another machine:

cmd
mstsc /admin /v:<server_ip>

In my case after disabling TLS RDP started working.

This is a crucial diagnostic result.

It means:

  • port 3389 is functional;
  • TermService is functional;
  • listener rdp-tcp is functional;
  • administrator logon rights exist;
  • the problem is not the firewall;
  • the problem is not RemoteApp;
  • the problem is specifically RDP TLS / certificate / SChannel.

8. Confirmation via Event Viewer

After connection attempts with TLS there was an error in the Event Viewer:

Event ID: 1057
Provider: Microsoft-Windows-TerminalServices-RemoteConnectionManager
Level: Error

The Remote Desktop Session Host server failed to create
a new self-signed certificate to be used to authenticate the
Remote Desktop Session Host server for SSL connections.

Status code: The specified algorithm is incorrect.

“The specified algorithm is incorrect” is the textual description of the NTE_BAD_ALGID (0x80090008) error from the Windows Crypto API. It is exactly this that causes the client to see “An internal error has occurred” or 0x904 / 0x7.

You can view such events with:

powershell
Get-WinEvent `
  -LogName System `
  -MaxEvents 200 |
Where-Object {
    $_.ProviderName -eq 'Microsoft-Windows-TerminalServices-RemoteConnectionManager' -and
    $_.Id -eq 1057
} |
Select-Object TimeCreated, Id, ProviderName, LevelDisplayName, Message |
Format-List

It’s also useful to check RDP logs:

powershell
Get-WinEvent `
  -LogName 'Microsoft-Windows-RemoteDesktopServices-RdpCoreTS/Admin' `
  -MaxEvents 50 |
Select-Object TimeCreated, Id, LevelDisplayName, Message |
Format-List
powershell
Get-WinEvent `
  -LogName 'Microsoft-Windows-RemoteDesktopServices-RdpCoreTS/Operational' `
  -MaxEvents 50 |
Select-Object TimeCreated, Id, LevelDisplayName, Message |
Format-List

And SChannel:

powershell
Get-WinEvent -LogName System -MaxEvents 200 |
Where-Object {
    $_.ProviderName -eq 'Schannel' -or
    $_.Message -match 'TLS|SSL|certificate|сертификат|handshake'
} |
Select-Object TimeCreated, Id, ProviderName, LevelDisplayName, Message |
Format-List

9. Why Event ID 1057 occurs

Normally Windows Server can automatically create a self-signed certificate for RDP. That certificate is used to authenticate the server during TLS connections.

Error 1057 means Windows could not create such a certificate.

Causes can be various:

  1. a crypto provider is corrupted or unavailable;
  2. permissions on MachineKeys are incorrect;
  3. strict crypto/FIPS policies are enabled;
  4. required TLS/SChannel algorithms have been disabled;
  5. an old RDP certificate binding is corrupted;
  6. a certificate was deleted but Windows cannot create a new one;
  7. an inappropriate algorithm/provider was used;
  8. settings were changed by hardening tools like IIS Crypto or GPO;
  9. cryptographic system components are damaged.

In my case the fastest and correct recovery path was not to wait for TermService auto-generation, but to create the certificate manually and explicitly bind it to RDP-tcp.


10. Before fixing: make a backup

Before changing RDP settings save the current registry key:

cmd
mkdir C:\Temp 2>nul

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

Also save current parameters:

powershell
$RdpTcp = 'HKLM:\SYSTEM\CurrentControlSet\Control\Terminal Server\WinStations\RDP-Tcp'

Get-ItemProperty $RdpTcp |
Select-Object `
  PortNumber,
  UserAuthentication,
  SecurityLayer,
  MinEncryptionLevel,
  fEnableWinStation,
  SSLCertificateSHA1Hash |
Out-File C:\Temp\RDP-Tcp-before.txt

11. Check FIPS policy

The “specified algorithm is incorrect” error can be related to crypto policy. Check FIPS:

powershell
Get-ItemProperty `
  'HKLM:\SYSTEM\CurrentControlSet\Control\Lsa\FipsAlgorithmPolicy' `
  -ErrorAction SilentlyContinue |
Select-Object Enabled

If:

Enabled : 1

then FIPS is enabled.

You should also check the result of group policies:

cmd
gpresult /h C:\Temp\gpresult.html

In the report look for:

System cryptography: Use FIPS compliant algorithms for encryption, hashing, and signing

If the server is in a domain and FIPS is enabled via GPO, you should not disable it locally. Local changes may be reverted, and the policy could be enabled for security compliance reasons.


12. Check TLS 1.2 in SChannel

On Windows Server 2019 it’s normal to use TLS 1.2 for RDP.

Check TLS settings:

powershell
$paths = @(
  'HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.2\Client',
  'HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.2\Server',
  'HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.0\Client',
  'HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.0\Server',
  'HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.1\Client',
  'HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.1\Server'
)

foreach ($path in $paths) {
    Write-Host "`n$path" -ForegroundColor Cyan

    Get-ItemProperty $path -ErrorAction SilentlyContinue |
    Select-Object Enabled, DisabledByDefault
}

If TLS 1.2\Server exists and there:

Enabled : 0

or:

DisabledByDefault : 1

then TLS 1.2 on the server side is disabled.

By the way, disabled TLS 1.2 on the server is itself a common cause of the client “An internal error has occurred” even when the certificate is fine: a modern client simply cannot negotiate a protocol.

You can enable TLS 1.2 like this:

powershell
$Tls12Server = 'HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.2\Server'
$Tls12Client = 'HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.2\Client'

New-Item -Path $Tls12Server -Force | Out-Null
New-Item -Path $Tls12Client -Force | Out-Null

New-ItemProperty -Path $Tls12Server -Name Enabled -Value 1 -PropertyType DWord -Force | Out-Null
New-ItemProperty -Path $Tls12Server -Name DisabledByDefault -Value 0 -PropertyType DWord -Force | Out-Null

New-ItemProperty -Path $Tls12Client -Name Enabled -Value 1 -PropertyType DWord -Force | Out-Null
New-ItemProperty -Path $Tls12Client -Name DisabledByDefault -Value 0 -PropertyType DWord -Force | Out-Null

After changing SChannel settings a reboot is often required. But first you can restore the RDP certificate and check operation.


13. Check permissions on MachineKeys

Windows stores machine private keys here:

C:\ProgramData\Microsoft\Crypto\RSA\MachineKeys

If ACLs on the folder are broken, services may not be able to create or read private keys.

Save current ACLs:

cmd
mkdir C:\Temp 2>nul
icacls C:\ProgramData\Microsoft\Crypto\RSA\MachineKeys /t /c > C:\Temp\MachineKeys-before.txt

Basic repair of permissions:

cmd
takeown /f "C:\ProgramData\Microsoft\Crypto\RSA\MachineKeys" /a /r

icacls "C:\ProgramData\Microsoft\Crypto\RSA\MachineKeys" /t /c /grant "NT AUTHORITY\SYSTEM:(F)"
icacls "C:\ProgramData\Microsoft\Crypto\RSA\MachineKeys" /t /c /grant "BUILTIN\Administrators:(F)"
icacls "C:\ProgramData\Microsoft\Crypto\RSA\MachineKeys" /t /c /grant "NT AUTHORITY\NETWORK SERVICE:(R)"
icacls "C:\ProgramData\Microsoft\Crypto\RSA\MachineKeys" /t /c > C:\Temp\MachineKeys-after.txt

This is a recovery step. In production it’s better to preserve original ACLs and understand which policies manage the permissions.


14. Remove old RDP TLS binding

Remove the old certificate hash from RDP-Tcp:

powershell
$RdpTcp = 'HKLM:\SYSTEM\CurrentControlSet\Control\Terminal Server\WinStations\RDP-Tcp'

Remove-ItemProperty `
  -Path $RdpTcp `
  -Name SSLCertificateSHA1Hash `
  -ErrorAction SilentlyContinue

Remove old RDP self-signed certificates from the Remote Desktop store:

powershell
Get-ChildItem 'Cert:\LocalMachine\Remote Desktop' -ErrorAction SilentlyContinue |
Remove-Item -Force

Check what’s left:

powershell
Get-ChildItem 'Cert:\LocalMachine\Remote Desktop' -ErrorAction SilentlyContinue |
Select-Object Subject, Thumbprint, NotAfter

15. Create a new certificate manually

Key point: it’s better to create the certificate explicitly with RSA/SHA256 and a compatible crypto provider.

In my case I used:

Microsoft RSA SChannel Cryptographic Provider

Command:

powershell
$ComputerSystem = Get-CimInstance Win32_ComputerSystem

$DnsNames = @($env:COMPUTERNAME)

if ($ComputerSystem.PartOfDomain) {
    $DnsNames += "$env:COMPUTERNAME.$($ComputerSystem.Domain)"
}

$Cert = New-SelfSignedCertificate `
  -DnsName $DnsNames `
  -CertStoreLocation 'Cert:\LocalMachine\My' `
  -Provider 'Microsoft RSA SChannel Cryptographic Provider' `
  -KeyAlgorithm RSA `
  -KeyLength 2048 `
  -HashAlgorithm SHA256 `
  -KeySpec KeyExchange `
  -KeyUsage DigitalSignature, KeyEncipherment `
  -NotAfter (Get-Date).AddYears(3) `
  -TextExtension @('2.5.29.37={text}1.3.6.1.5.5.7.3.1')

$Cert |
Select-Object Subject, Thumbprint, NotAfter, HasPrivateKey

You need to ensure:

HasPrivateKey : True

Without the private key such a certificate is useless for RDP.

Grant TermService access to the private key

TermService runs as NETWORK SERVICE. If that account does not have permission to read the private key, RDP will not be able to use the certificate — and you’ll get the same client “internal error” even with a new certificate.

Grant rights to the key file:

powershell
$RsaKey = [System.Security.Cryptography.X509Certificates.RSACertificateExtensions]::GetRSAPrivateKey($Cert)
$KeyFile = $RsaKey.Key.UniqueName
$KeyPath = Join-Path 'C:\ProgramData\Microsoft\Crypto\RSA\MachineKeys' $KeyFile

icacls $KeyPath /grant 'NT AUTHORITY\NETWORK SERVICE:(R)'

Check:

powershell
icacls $KeyPath

The output should include a line with NT AUTHORITY\NETWORK SERVICE:(R).


16. Bind the certificate to the RDP listener

Now assign the certificate to RDP-tcp.

powershell
$RdpSetting = Get-WmiObject `
  -Namespace 'root\cimv2\TerminalServices' `
  -Class 'Win32_TSGeneralSetting' `
  -Filter "TerminalName='RDP-tcp'"

Set-WmiInstance `
  -Path $RdpSetting.__PATH `
  -Arguments @{ SSLCertificateSHA1Hash = $Cert.Thumbprint }

Check:

powershell
Get-WmiObject `
  -Namespace 'root\cimv2\TerminalServices' `
  -Class 'Win32_TSGeneralSetting' `
  -Filter "TerminalName='RDP-tcp'" |
Select-Object TerminalName, SSLCertificateSHA1Hash

Also check the registry:

powershell
Get-ItemProperty `
  'HKLM:\SYSTEM\CurrentControlSet\Control\Terminal Server\WinStations\RDP-Tcp' |
Select-Object SSLCertificateSHA1Hash

The value should not be empty.


17. Return RDP from emergency mode

Don’t immediately return to forced TLS SecurityLayer = 2.

First set a safe intermediate option:

powershell
$RdpTcp = 'HKLM:\SYSTEM\CurrentControlSet\Control\Terminal Server\WinStations\RDP-Tcp'

Set-ItemProperty -Path $RdpTcp -Name SecurityLayer -Value 1
Set-ItemProperty -Path $RdpTcp -Name MinEncryptionLevel -Value 2
Set-ItemProperty -Path $RdpTcp -Name UserAuthentication -Value 0

Restart-Service TermService -Force

Check locally:

cmd
mstsc /admin /v:127.0.0.1

Check from outside:

cmd
mstsc /admin /v:<server_ip_or_fqdn>

If it works — re-enable NLA:

powershell
Set-ItemProperty `
  -Path 'HKLM:\SYSTEM\CurrentControlSet\Control\Terminal Server\WinStations\RDP-Tcp' `
  -Name UserAuthentication `
  -Value 1

Restart-Service TermService -Force

Check again:

cmd
mstsc /admin /v:<server_ip_or_fqdn>

18. Can you return SecurityLayer = 2

If you want to force TLS, after successful checks with SecurityLayer = 1 you can try:

powershell
$RdpTcp = 'HKLM:\SYSTEM\CurrentControlSet\Control\Terminal Server\WinStations\RDP-Tcp'

Set-ItemProperty -Path $RdpTcp -Name SecurityLayer -Value 2
Set-ItemProperty -Path $RdpTcp -Name MinEncryptionLevel -Value 3
Set-ItemProperty -Path $RdpTcp -Name UserAuthentication -Value 1

Restart-Service TermService -Force

Check:

cmd
mstsc /admin /v:<server_ip_or_fqdn>

If everything works with SecurityLayer = 1 but breaks again with SecurityLayer = 2, it means TLS/SChannel/certificate policy issues are not fully resolved.

In that case it’s better to temporarily keep:

SecurityLayer = 1
UserAuthentication = 1
MinEncryptionLevel = 2 or 3

This is much better than the emergency mode:

SecurityLayer = 0

19. Check whether error 1057 has disappeared

After restoring the certificate and restarting TermService check the Event Viewer:

powershell
Get-WinEvent `
  -LogName System `
  -MaxEvents 100 |
Where-Object {
    $_.ProviderName -eq 'Microsoft-Windows-TerminalServices-RemoteConnectionManager' -and
    $_.Id -eq 1057
} |
Select-Object TimeCreated, Id, LevelDisplayName, Message |
Format-List

If there are no new 1057 events after the restart, that’s a good sign.

You can also look at related events:

powershell
Get-WinEvent `
  -LogName System `
  -MaxEvents 100 |
Where-Object {
    $_.ProviderName -eq 'Microsoft-Windows-TerminalServices-RemoteConnectionManager' -and
    $_.Id -in 1056,1057,1058
} |
Select-Object TimeCreated, Id, LevelDisplayName, Message |
Format-List

20. Check RDP policies via GPO

If the server is domain-joined, settings may come from Group Policy.

Create a report:

cmd
gpresult /h C:\Temp\gpresult.html

In the report look for:

Computer Configuration
  Administrative Templates
    Windows Components
      Remote Desktop Services
        Remote Desktop Session Host
          Security

Policies of particular interest:

Require use of specific security layer for remote (RDP) connections
Require user authentication for remote connections by using Network Level Authentication
Set client connection encryption level
Server authentication certificate template

Also check registry-policies:

powershell
Get-ItemProperty `
  'HKLM:\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services' `
  -ErrorAction SilentlyContinue |
Select-Object SecurityLayer, UserAuthentication, MinEncryptionLevel, SSLCertificateSHA1Hash

If something like:

SecurityLayer : 2

is set there, local changes may be reverted after gpupdate.


21. What to do with RemoteApp and RDWeb after RDP recovery

After regular RDP works, you can return to RemoteApp.

In my case W3SVC was stopped and disabled:

W3SVC  Stopped  Disabled

This is a problem for RD Web Access.

Enable IIS:

powershell
Set-Service W3SVC -StartupType Automatic
Start-Service W3SVC

Check:

powershell
Get-Service W3SVC

Check RDWeb availability:

https://<server_fqdn>/RDWeb

If RD Gateway is used, check:

powershell
Get-Service TSGateway -ErrorAction SilentlyContinue

And logs:

powershell
Get-WinEvent `
  -LogName 'Microsoft-Windows-TerminalServices-Gateway/Operational' `
  -MaxEvents 50 |
Select-Object TimeCreated, Id, LevelDisplayName, Message |
Format-List

Check the RDS deployment:

powershell
Import-Module RemoteDesktop

Get-RDServer
Get-RDSessionCollection
Get-RDRemoteApp

Check collection permissions:

powershell
Get-RDSessionCollection | ForEach-Object {
    Write-Host "`nCollection: $($_.CollectionName)" -ForegroundColor Cyan

    Get-RDSessionCollectionConfiguration `
      -CollectionName $_.CollectionName `
      -UserGroup
}

22. Minimal recovery checklist

If you need to quickly restore access, the order is as follows.

1. Check the listener

cmd
qwinsta
change logon /query

Should be:

rdp-tcp  Listen
Session logons are currently ENABLED

2. Check RDP parameters

powershell
$RdpTcp = 'HKLM:\SYSTEM\CurrentControlSet\Control\Terminal Server\WinStations\RDP-Tcp'

Get-ItemProperty $RdpTcp |
Select-Object PortNumber, UserAuthentication, SecurityLayer, MinEncryptionLevel, fEnableWinStation, SSLCertificateSHA1Hash

3. If you need to get in urgently — temporarily disable TLS

powershell
Set-ItemProperty -Path $RdpTcp -Name UserAuthentication -Value 0
Set-ItemProperty -Path $RdpTcp -Name SecurityLayer -Value 0
Set-ItemProperty -Path $RdpTcp -Name MinEncryptionLevel -Value 1

Restart-Service TermService -Force

Check:

cmd
mstsc /admin /v:<server_ip>

4. Check Event ID 1057

powershell
Get-WinEvent `
  -LogName System `
  -MaxEvents 200 |
Where-Object {
    $_.ProviderName -eq 'Microsoft-Windows-TerminalServices-RemoteConnectionManager' -and
    $_.Id -eq 1057
} |
Select-Object TimeCreated, Id, ProviderName, LevelDisplayName, Message |
Format-List

5. Create and bind a new RSA/SHA256 certificate

powershell
$RdpTcp = 'HKLM:\SYSTEM\CurrentControlSet\Control\Terminal Server\WinStations\RDP-Tcp'

Remove-ItemProperty `
  -Path $RdpTcp `
  -Name SSLCertificateSHA1Hash `
  -ErrorAction SilentlyContinue

Get-ChildItem 'Cert:\LocalMachine\Remote Desktop' -ErrorAction SilentlyContinue |
Remove-Item -Force

$ComputerSystem = Get-CimInstance Win32_ComputerSystem
$DnsNames = @($env:COMPUTERNAME)

if ($ComputerSystem.PartOfDomain) {
    $DnsNames += "$env:COMPUTERNAME.$($ComputerSystem.Domain)"
}

$Cert = New-SelfSignedCertificate `
  -DnsName $DnsNames `
  -CertStoreLocation 'Cert:\LocalMachine\My' `
  -Provider 'Microsoft RSA SChannel Cryptographic Provider' `
  -KeyAlgorithm RSA `
  -KeyLength 2048 `
  -HashAlgorithm SHA256 `
  -KeySpec KeyExchange `
  -KeyUsage DigitalSignature, KeyEncipherment `
  -NotAfter (Get-Date).AddYears(3) `
  -TextExtension @('2.5.29.37={text}1.3.6.1.5.5.7.3.1')

$RsaKey = [System.Security.Cryptography.X509Certificates.RSACertificateExtensions]::GetRSAPrivateKey($Cert)
$KeyPath = Join-Path 'C:\ProgramData\Microsoft\Crypto\RSA\MachineKeys' $RsaKey.Key.UniqueName
icacls $KeyPath /grant 'NT AUTHORITY\NETWORK SERVICE:(R)'

$RdpSetting = Get-WmiObject `
  -Namespace 'root\cimv2\TerminalServices' `
  -Class 'Win32_TSGeneralSetting' `
  -Filter "TerminalName='RDP-tcp'"

Set-WmiInstance `
  -Path $RdpSetting.__PATH `
  -Arguments @{ SSLCertificateSHA1Hash = $Cert.Thumbprint }

6. Return to normal mode

powershell
Set-ItemProperty -Path $RdpTcp -Name SecurityLayer -Value 1
Set-ItemProperty -Path $RdpTcp -Name MinEncryptionLevel -Value 2
Set-ItemProperty -Path $RdpTcp -Name UserAuthentication -Value 0

Restart-Service TermService -Force

Check:

cmd
mstsc /admin /v:<server_ip>

If it works — re-enable NLA:

powershell
Set-ItemProperty -Path $RdpTcp -Name UserAuthentication -Value 1

Restart-Service TermService -Force

23. What not to do

Do not leave SecurityLayer = 0

This is an emergency mode. It helped prove that the problem was TLS, but it is not suitable for permanent use.

Do not start by reinstalling RDS

If rdp-tcp is listening and RDP comes alive without TLS, reinstalling RDS is almost certainly unnecessary.

Do not try to fix RemoteApp while regular mstsc is not working

RemoteApp depends on RDP. If the underlying RDP doesn’t work, RemoteApp diagnostics will be noisy and ineffective.

Do not ignore GPO

If security settings come from domain policy, local fixes may be reverted.

Do not delete certificates blindly without understanding

Deleting an RDP self-signed certificate is usually safe, but if a corporate certificate was assigned, you’ll need to assign it again.


24. Why this solution worked

Diagnostics showed:

Port 3389 is open
TermService is running
rdp-tcp is listening
Logons are allowed
RDP without TLS works
RDP with TLS does not work
Event ID 1057: TermService cannot create a self-signed certificate

So the problem was not the network, not the firewall, and not administrator rights.

The root cause was in the chain:

TermService → RDP TLS certificate → SChannel / crypto provider → TLS handshake

Manually creating an RSA/SHA256 certificate and explicitly binding it to RDP-tcp removes the dependency on the broken auto-generation of the certificate.

After that you can return to reasonable security settings:

SecurityLayer = 1
UserAuthentication = 1

And only after that deal with RemoteApp, RDWeb, RD Gateway and RDS collections.


25. Conclusion

If RDP stops working on Windows Server 2019 but port 3389 is open, don’t limit yourself to checking the firewall. An open TCP port does not mean RDP successfully completes TLS/NLA/CredSSP.

From the client side such a failure looks like “An internal error has occurred” or error code 0x904 with extended code 0x7. Decoding these client-side codes is useless — the cause is on the server.

In my case the key to diagnosis was the comparison:

SecurityLayer = 2  → RDP does not work
SecurityLayer = 0  → RDP works

And confirmation in the Event Viewer:

Event ID 1057
Failed to create a new self-signed certificate
Status code: The specified algorithm is incorrect.

Correct remediation:

  1. temporarily restore access via SecurityLayer = 0;
  2. do not keep this mode permanently;
  3. remove the old RDP TLS binding;
  4. create a new RSA/SHA256 certificate;
  5. give NETWORK SERVICE access to its private key;
  6. explicitly assign the certificate to RDP-tcp;
  7. return SecurityLayer = 1;
  8. re-enable NLA;
  9. check GPO and SChannel;
  10. after recovering the base RDP, fix RDWeb/RemoteApp.

Main idea: RemoteApp cannot be diagnosed while regular RDP does not work. First you must bring up the basic RDP listener with proper TLS, and only then troubleshoot higher RDS roles.

// Reviews

Related reviews

I came with an expensive request to configure a VPS server, but during the consultation Mikhail suggested a much simpler, more affordable solution. In the end I saved time and money. Mikhail — a true expert who works for the client's result, not for the fee. I recommend him!

I came with an expensive request to configure a VPS server, but during the consultation Mikhail suggested a much simpler and more cost-effective solution. In the end I saved budget and time. Mikhail — a true expert who …

kfhzasorin

VPS setup, server setup

2026-05-12 · ★ 5/5

// Contact

Need help?

Get in touch with me and I'll help solve the problem

Message on Telegram

Отвечаю в течение рабочего дня (03:00–13:00 GMT)

Или оставьте заявку здесь:

Write and get a quick reply