| name | windows-rdp-login-troubleshooting |
| description | Diagnose and fix Windows Remote Desktop (RDP) login or connection failures, especially over Tailscale/VPN and especially for PCs signed in with a Microsoft account. Use this WHENEVER the user reports RDP trouble on Windows โ "RDP ๋ก๊ทธ์ธ์ด ์ ๋ผ์" / "remote desktop credentials rejected" / "์๊ฒฉ ์ฆ๋ช
์ด ์๋ํ์ง ์์ต๋๋ค" / "can't connect to my PC over Tailscale" / "Windows Hello only sign-in blocks remote login" / PIN-vs-password confusion / NLA failures / "remote desktop keeps disconnecting after a few seconds". Covers the read-only diagnostic sweep (RDP enabled, TermService, port 3389, firewall incl. localized rule names, NLA, account type/admin/lockout, Tailscale), the crucial "can't connect vs credentials rejected" fork, Microsoft-account gotchas (DevicePasswordLessBuildVersion / Windows-Hello-only toggle needing a reboot, username format, passwordless accounts, stale cached password), event-log forensics, and account-lockout confounders. Trigger even if the user doesn't say the word "RDP" but clearly can't remote into a Windows box. |
Windows RDP Login Troubleshooting (Tailscale / Microsoft account)
Why this skill exists
RDP failures split into two completely different problems that look similar to a
frustrated user but need opposite fixes:
- (A) Can't connect โ the client times out / "can't reach the computer."
Root cause is network, firewall, service, or Tailscale.
- (B) Connects, but login is rejected โ you reach a credential prompt and it
says "์๊ฒฉ ์ฆ๋ช
์ด ์๋ํ์ง ์์ต๋๋ค / The credentials that were used to connect
did not work." Root cause is authentication/account, not the network.
Guessing wastes time and can lock the account. Gather read-only evidence
first, identify which branch you're in, then fix the root cause. Do not change
any system setting until the evidence points at it.
The single most common hard-to-spot root cause on modern Windows 11 is the
"Windows Hello sign-in only" toggle for Microsoft accounts โ it rejects a
100%-correct password over RDP and needs a reboot after being turned off.
Keep it top of mind for branch (B).
Step 0 โ Run the diagnostic sweep (read-only, safe)
Run the bundled script. It makes no changes and prints everything needed to
pick a branch:
powershell -ExecutionPolicy Bypass -File "<skill-dir>\scripts\diagnose-rdp.ps1"
If the current shell is not elevated, the Security event log section will be
unreadable โ that's expected; note it and continue. Everything else works
unelevated.
Read the output, then map it against the checks below.
Step 1 โ What "good" looks like (host side)
| Check | Healthy value | Meaning if wrong |
|---|
whoami | PC\user | confirms which account/computer you're on |
RDP enabled (fDenyTSConnections) | 0 | 1 = RDP turned off โ enable it |
TermService | Running | stopped โ start it / set to Manual+trigger |
| Port 3389 listening | 0.0.0.0 + :: | not listening โ service/RDP off |
| Firewall RDP rule | Enabled, Allow, applies to the connecting profile | blocked โ see Branch A |
| Edition | Pro/Enterprise/Education | Home cannot host RDP (no incoming) |
| Account | enabled, Administrator or in Remote Desktop Users | else not authorized |
Localization gotcha (important): never search firewall rules by the English
name "Remote Desktop" on a non-English Windows. On Korean Windows the rule is
์๊ฒฉ ๋ฐ์คํฌํฑ - ์ฌ์ฉ์ ๋ชจ๋(TCP-In). Always match by port 3389, which is
language-independent (the script already does this). A "no rules found" result
from an English-name search is almost always a false negative.
Step 2 โ Pick the branch: connect vs. credentials
Determine the exact client-side symptom (ask the user if unknown โ it's the most
decisive single data point):
- "์ฐ๊ฒฐํ ์ ์์ต๋๋ค / can't connect", never reach a password box โ Branch A.
- "์๊ฒฉ ์ฆ๋ช
์ด ์๋ํ์ง ์์ต๋๋ค / credentials did not work" after typing the
password โ Branch B.
- "๋ด๋ถ ์ค๋ฅ / internal error", or black screen then drops after a few
seconds โ usually transport/NLA โ start with Branch A (MTU/Tailscale), then B.
Confirm with the host event logs (the script pulls these):
TerminalServices-RemoteConnectionManager/Operational 261 = "listener
received a connection" โ the client did reach this PC (rules out pure
network/firewall to the box).
- 1149 in the same log = "user authentication succeeded." Its absence
across all attempts = no successful auth yet.
LocalSessionManager/Operational 21/25 = a session actually logged on.
Absent = no successful session.
RdpCoreTS/Operational error 64 / 0x80070040 (ERROR_NETNAME_DELETED) =
the TCP socket dropped. With NLA this commonly appears as a side effect of a
credential rejection (client tears down the connection) โ so error 64 +
"credentials did not work" still points to Branch B, not transport.
Branch A โ Can't connect (network / transport)
Work outside-in:
- Tailscale up on both ends.
tailscale status โ is this node online, and
is the client device online (not "offline, last seen โฆ")? Connect to the
tailnet IP (e.g. 100.x.y.z) or MagicDNS name.
- Firewall allows inbound 3389 on the profile of the incoming interface.
Tailscale's adapter usually classifies as Private; the LAN/Ethernet may be
Public. Make sure the RDP rule covers that profile (
Profile = Any covers
all). Check Get-NetConnectionProfile.
- Port listening / service running (Step 1).
- MTU / large-packet drops over the tunnel. Symptom: connects then dies in a
few seconds, black screen, error 64, "internal error." Test plain reachability
Test-NetConnection <tailnet-ip> -Port 3389. If TCP connects but RDP stalls,
suspect MTU; try the RDP client option to use a lower connection quality, or
investigate Tailscale MTU.
Branch B โ Connects but credentials rejected (Microsoft account)
This is where most real-world cases land. Check causes in this order โ the
first ones are both common and invisible:
B1. "Windows Hello sign-in only" toggle (most common, sneaky)
Registry: HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\PasswordLess\Device
โ DevicePasswordLessBuildVersion.
2 = the Settings toggle "๋ณด์ ๊ฐํ๋ฅผ ์ํด ์ด ์ฅ์น์์ Microsoft ๊ณ์ ์
Windows Hello ๋ก๊ทธ์ธ๋ง ํ์ฉ" / "For improved security, only allow Windows Hello
sign-in for Microsoft accounts on this device" is ON. Password auth for
the MS account is blocked, including over RDP โ a correct password is
rejected and often no 4625/4776 is logged (policy blocks it before
validation).
- Fix: Settings โธ ๊ณ์ โธ ๋ก๊ทธ์ธ ์ต์
โ turn the toggle off (or set the
value to
0), then REBOOT. Turning it off without a reboot leaves the live
LSA policy still blocking password sign-in โ the registry reads 0 but RDP
still fails. The reboot is the part people miss.
# elevated
Set-ItemProperty 'HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\PasswordLess\Device' -Name DevicePasswordLessBuildVersion -Value 0 -Type DWord
# then reboot
B2. Username format
For a Microsoft-account PC, do not use the display name (chris) or
PC\name. Use the account email, and if plain email fails,
MicrosoftAccount\email@domain. Wrong format โ "credentials did not work" even
with the right password.
B3. PIN โ password
RDP (standard NLA) cannot use Windows Hello (PIN/face/fingerprint). The user must
type the actual Microsoft-account password. People who only ever use a PIN
often type the PIN, or have forgotten the real password (reset at
account.microsoft.com).
B4. Passwordless Microsoft account
If the online MS account is passwordless, there is no password to present over
RDP. Add a password to the account, or use the local-account fallback below.
(Get-LocalUser <name> showing PasswordLastSet populated suggests a password
exists locally, but the online account can still be passwordless.)
B5. Stale / changed cached password โ decisive isolation test
The PIN is device-bound and survives an online password change, so the user may
not notice the password they "know" differs from what the device accepts.
Test: on the physical machine, Win+L, then unlock using the password
option (not PIN).
- Fails locally too โ the password itself is wrong/stale (not an RDP problem).
- Works locally but RDP fails โ it's RDP/policy (revisit B1/B2).
B6. Authorization
The account must be enabled and either an Administrator or a member of
Remote Desktop Users. Admins are allowed by default; an empty Remote Desktop
Users group is fine if the user is an admin.
The lockout confounder (check before retrying)
Default policy may lock the account after N failed attempts. The script prints
net accounts (e.g. threshold 10, duration 10 min, window 10 min). Repeated
testing trips this, after which even a correct password fails for the
duration. Symptoms of a fix that "still doesn't work" are often just an active
lockout. Guidance: between attempts, wait out the lockout window and try
exactly once, don't hammer it.
Pinpoint the exact reason (elevated)
To distinguish wrong-password vs locked vs policy-block definitively, read the
Security log right after one failed attempt, in an elevated shell:
Get-WinEvent -FilterHashtable @{LogName='Security'; Id=4776,4625,4740} -MaxEvents 5 | Format-List TimeCreated, Id, Message
Interpret the status/sub-status code:
0x0 success ยท 0xC000006A wrong password ยท 0xC0000234 account locked ยท
0xC0000064 no such user ยท 0xC000006D generic failure.
- No 4625/4776 at all despite a rejected login โ consistent with the B1
policy block (reboot needed) โ provided the log is actually readable (an
unelevated shell can't read Security and will misleadingly report "no events").
Reliable fallback: use a local account for RDP
If the Microsoft account keeps fighting (passwordless, policy, 2FA), the
guaranteed-working path is a local account: set a password on an existing
local user (or create one), add it to Remote Desktop Users (or
Administrators), and RDP with PC\localuser. This sidesteps all MS-account
policy entirely. Offer this when B1โB5 stall.
Notes worth telling the user
- Single session: on Windows Pro, RDP-ing in as the same user who is logged
in at the console disconnects the local session and moves it to the remote
โ normal, not an error.
- Security: re-enabling MS-account password sign-in (B1 fix) slightly lowers
the device's posture. Over Tailscale the exposure is limited to the tailnet;
for tighter control, restrict port 3389 to specific devices via a Tailscale
ACL rather than exposing it broadly.
Order of operations (summary)
- Run
diagnose-rdp.ps1 (read-only).
- Confirm host basics are green (RDP on, service up, port listening, firewall by
port, edition Pro+, account authorized).
- Get the client-side symptom โ choose Branch A or B.
- Fix the identified root cause. For B1, set value 0 AND reboot.
- Mind the lockout window โ try once, not many times.
- If MS-account auth stays broken, fall back to a local account.