Troubleshooting SDE VDI desktop pools

By Paul Flanders · · Intermediate

This article provides troubleshooting steps for resolving issues with SDE VDI desktop pools, such as sign-in problems and unexpected recycling of desktops. It includes detailed instructions and solutions for engineers managing SDE VDI environments.

What to check when a pool desktop won't become ready, a user can't sign in, or a desktop is recycled sooner or later than expected. Each problem is listed with its cause and the fix.

Applies to: sde-vdi 0.5.9, SDE Remote gateway 1.0.12, SDE Remote app 1.1.2 · Audience: engineers running SDE VDI · Time: 5–30 minutes per problem

1. Where to look first

WhereWhat it tells you
Admin page → DesktopsEach desktop's state and preparation step. Errors show in red under the desktop's name, including errors from a step that's being retried.
Admin page → ReadinessLive checks of Proxmox, Guacamole, the gateway and Active Directory. Each problem comes with its fix. Click Run checks again after a change.
Admin page → ActivityThe last 500 events: clones, ready, assigned, lease ended (with the reason), DNS repairs, errors. Type a desktop or user name in the filter.
Admin page → OverviewA pool showing Can't add desktops. gives the reason, for example a missing template.
docker logs sde-vdiThe full history. AUDIT vdi-… lines are the events; WARN lines carry the error from a failed rename, join, trust repair or DNS repair.
docker logs sde-gatewayWhat the gateway asked for and why it was refused, e.g. AUDIT vdi-authorize REFUSED user=… reason=….
The SDE Remote appThe message the user saw. A FreeRDP failure message ends with the path of the FreeRDP log.
docker logs sde-vdi 2>&1 | grep -E 'AUDIT|WARN|ERROR' | tail -50
docker logs sde-vdi 2>&1 | grep W11-OFF-003            # one desktop's history
docker logs sde-gateway 2>&1 | grep vdi | tail -20

2. Look inside a desktop from Proxmox

sde-vdi does everything inside a desktop through the QEMU guest agent, and you can too. You don't need the desktop's password or network access to it. Commands run as SYSTEM.

  1. On the Desktops tab, note the desktop's Node · VMID.
  2. Open the Shell of that node in Proxmox (qm only works on the node that holds the VM).
  3. Run the commands below, with your VMID and domain. The answer comes back as JSON; the command's output is in out-data.

2.1 Who is signed in

qm guest exec 10457 -- cmd /c "query user"

sde-vdi reads the same list. A session in state Active is never recycled; Disc means disconnected.

2.2 Read the event logs

# Failed sign-ins (the Status and Sub Status lines give the reason)
qm guest exec 10457 --timeout 60 -- powershell -NoProfile -Command "Get-WinEvent -FilterHashtable @{LogName='Security'; Id=4625} -MaxEvents 5 | Format-List TimeCreated, Message"

# DNS registration refused (stale record, section 4)
qm guest exec 10457 --timeout 60 -- powershell -NoProfile -Command "Get-WinEvent -FilterHashtable @{LogName='System'; Id=8018} -MaxEvents 3 | Format-List TimeCreated, Message"

# The latest System events
qm guest exec 10457 --timeout 60 -- powershell -NoProfile -Command "Get-WinEvent -LogName System -MaxEvents 30 | Format-Table -AutoSize TimeCreated, Id, ProviderName, Message"

Keep -MaxEvents small: the guest agent returns a limited amount of output.

2.3 Check the domain trust with nltest

qm guest exec 10457 -- cmd /c "nltest /dsgetdc:lab.local"       # which DC it finds, or why it finds none
qm guest exec 10457 -- cmd /c "nltest /sc_query:lab.local"      # the secure channel's state and DC
qm guest exec 10457 -- cmd /c "nltest /sc_verify:lab.local"     # tests the channel properly
qm guest exec 10457 -- cmd /c "nltest /sc_reset:lab.local"      # sets the channel up again

A healthy desktop answers NERR_Success for /sc_query and /sc_verify.

2.4 Netlogon setting and debug log

# Should show UseKerberosForSecureChannels 0x0 on a desktop joined by sde-vdi 0.5.9 or later
qm guest exec 10457 -- cmd /c "reg query HKLM\SYSTEM\CurrentControlSet\Services\Netlogon\Parameters /v UseKerberosForSecureChannels"

# Netlogon debug log: switch on, try the sign-in again, read it, switch off
qm guest exec 10457 -- cmd /c "nltest /dbflag:0x2080ffff"
qm guest exec 10457 --timeout 60 -- powershell -NoProfile -Command "Get-Content C:\Windows\debug\netlogon.log -Tail 40"
qm guest exec 10457 -- cmd /c "nltest /dbflag:0x0"

2.5 Name and address

qm guest exec 10457 --timeout 60 -- powershell -NoProfile -Command "Resolve-DnsName W11-OFF-003.lab.local; ipconfig /all"

From the gateway host, nslookup W11-OFF-003.lab.local shows what sde-vdi and the gateway see.

3. Desktops that don't become ready

Every desktop must be ready within 20 minutes of starting to boot; after that it goes to Error with the last step in the message. Fix the cause, then use Delete now on the desktops in error so the pool builds fresh ones. The steps are described in the settings reference, section 14.

SymptomCauseFix
Stuck at Starting Windows/Linux, then "booting: the guest agent isn't answering yet (QEMU guest agent is not running)"Windows hasn't come up (boot loop, error screen, still installing updates), or the template's guest agent isn't installed or isn't enabledOpen the VM's Console in Proxmox. On the Templates tab, check the template shows Guest agent as passing. If not: enable Options → QEMU Guest Agent on the master, install the VirtIO guest tools, and release a new template version.
Stuck at Windows setup; Error "Windows is still on its setup screens after 20m0s"The unattend file doesn't skip the setup screensAdd SkipMachineOOBE and SkipUserOOBE to the unattend file and release a new version (Windows template guide, section 8).
Stuck at Joining the domain with "domain join: exit 1: … could not be contacted"The desktop can't find a domain controller: its DNS can't resolve the domain, or the DC it uses is downSet the pool's DNS servers for the domain to the DCs' addresses, two if you have them. Check with nltest /dsgetdc (2.3). sde-vdi retries the join every 5 minutes, so a DC that comes back within the 20 minutes lets the desktop carry on. Desktops already in Error need Delete now.
Joining the domain with "Access is denied"The join account isn't delegated on the pool's OURun ad-bootstrap-sde-vdi.ps1 -Check on a DC; Readiness checks the OU too (Pool … OU).
Goes between Checking domain trust and Repairing domain trustThe trust repair fails: the DC's clock is out, or the DC is down or not replicatingReadiness → DC clock. Fix the PDC's time source. A DC VM on Proxmox needs a Windows OS type, otherwise its clock runs on UTC.
Stuck at Granting Remote Desktop accessA group in Allow Remote Desktop for doesn't exist or is misspeltCorrect the pool field and save. The desktop tries again with the new value.
Stuck at Waiting for networkThe guest agent reports no usable address: no DHCP on that network, or IP range doesn't matchCheck DHCP on the pool's network (on an SDE Network, the network's own DHCP). Clear or correct IP range.
Stuck at waiting-dnsThe desktop's name still resolves to another addressSee section 4.
Stuck at Waiting for Remote Desktopsde-vdi can't reach the desktop's RDP portCheck Remote Desktop and its firewall rule in the template, and that the gateway host can reach the desktops' network on 3389.
Error "interrupted while cloning; delete it and let the pool refill"sde-vdi restarted while Proxmox was cloningDelete now.
Linux: Error "hostname is …, expected …"cloud-init didn't set the hostnameGive the template a CloudInit drive (Linux template guide).
Overview: Can't add desktops. "Template … not found in Proxmox"The pool's template name doesn't match a Proxmox templateChoose the template again in the pool editor. Names must match exactly.
Can't add desktops. "No node can take a clone of …"The allowed nodes are offline or short of memory, or the template is on another node's local storageFree memory, tick the template's node under Nodes, or copy the template (same name) to each node.
Can't add desktops. "Name pattern … has no free names left"Every number in the counter is in useUse a wider counter, e.g. {nnn} instead of {nn}.
Desktops shown as QuarantinedVMs tagged sde-vdi that sde-vdi doesn't know, for example after restoring the state fileCheck each one, then Delete now.

4. Name resolves to an old address

Symptom. New Windows desktops stay at the step waiting-dns, sometimes with an error such as "W11-OFF-001.lab.local still points at 10.250.2.102 (an older desktop's record Windows may not update)". Activity shows dns-repair events (was=10.250.2.102 now-registering=10.250.2.143). On the desktop, the System log has event 8018 (2.2).

Cause. A pool connects to desktops by name. Each Windows desktop registers its own DNS record, but the DC refuses the update when the record belongs to an older computer object of the same name. That happens when computer objects are deleted in AD and recreated: the join then makes a new object, and the old record keeps pointing at the previous desktop's address. RDP, and users, would go to the wrong machine.

What sde-vdi does. Before it checks RDP, sde-vdi makes sure a Windows desktop's name resolves to its own address. If it doesn't, sde-vdi deletes the old record over LDAP as the join account, then runs ipconfig /registerdns in the desktop, at most every 2 minutes. Normally the desktop is ready a few seconds after the repair.

Fix, when the repair doesn't work:

  • "no right to delete the DNS record": the join account may not delete records in that zone. Delete the desktop's A record in DNS Manager; sde-vdi registers it again on its next try. Zone scavenging also removes old records over time.
  • The name doesn't resolve at all from sde-vdi (Readiness → Pool … names resolve): give the gateway host the DCs as DNS servers, or clear the pool's DNS suffix to connect by IP address.
  • was=no record every time: the desktop's registration never arrives. Check the zone allows secure dynamic updates.
Avoid the causeDon't delete pool computer objects by hand while their names are in use. Recycled desktops keep their objects on purpose, so the next desktop of that name reuses them. Use Readiness → Active Directory clean-up, which only lists names that won't come back and removes their DNS records too.

5. Domain sign-ins refused on an SDE Network

Symptom. Every sign-in to a Windows pool on an SDE Network fails, while the same template on the LAN works. The app says "Windows refused the sign-in". On the desktop, Security event 4625 shows status 0xC000018D (the trust relationship failed). Readiness is green and the desktop passed Checking domain trust, because Kerberos itself works. With the Netlogon debug log on (2.4), netlogon.log shows "could not authenticate with Kerberos" (0xC0000022) and "unmatching capabilities".

Cause. Windows 11 (seen on 25H2) with a Windows Server 2025 DC first tries the newer Kerberos-based Netlogon secure channel. From an SDE Network that attempt fails. Windows falls back to the classic channel, but the DC refuses its capabilities check and Windows drops that channel too. Without a working channel the desktop can't check domain passwords for RDP sign-ins.

Fix. sde-vdi 0.5.9 sets the registry value UseKerberosForSecureChannels=0 (under HKLM\SYSTEM\CurrentControlSet\Services\Netlogon\Parameters) on every desktop as part of the join, and again before a trust repair. Windows then uses the classic channel, which works.

  • Desktops joined before 0.5.9: upgrade sde-vdi, then Delete now on the spare desktops. Desktops in use are replaced when their users sign out.
  • To fix one desktop by hand, from the node's Shell:
    qm guest exec 10457 -- powershell -NoProfile -Command "New-ItemProperty -Path 'HKLM:\SYSTEM\CurrentControlSet\Services\Netlogon\Parameters' -Name UseKerberosForSecureChannels -Value 0 -PropertyType DWord -Force; Restart-Service Netlogon -Force"
    qm guest exec 10457 -- cmd /c "nltest /sc_reset:lab.local"
    qm guest exec 10457 -- cmd /c "nltest /sc_verify:lab.local"
  • Check the setting with the reg query in 2.4.
SDE_VDI_NETLOGON_KERBEROSSetting SDE_VDI_NETLOGON_KERBEROS=true in the sde-vdi unit stops sde-vdi changing the setting, so desktops keep the Kerberos channel. Leave it unset unless you have a reason to need that channel and your desktops aren't on an SDE Network.

The same status, 0xC000018D, on a desktop that fails the trust check (it stays at Repairing domain trust) has a different cause, usually the DC's clock. See section 3.

6. Users can't connect

Message in SDE RemoteCauseFix
"Windows refused the sign-in: wrong username or password, or an account the server doesn't know …" (FreeRDP exit code 132)The desktop rejected the user's credentials at sign-inRead event 4625 on the desktop (2.2). Its status says why: 0xC000006D / 0xC000006A wrong password; 0xC0000064 unknown user; 0xC000018D broken trust (section 5); 0xC000015B no Remote Desktop right (set Allow Remote Desktop for or a GPO). A Guacamole-only account can't sign in to Windows at all (section 7).
"… is an SDE-only account, so it can't sign in to the desktops in …"A Guacamole-only account tried a pool that passes the user's sign-in throughSee section 7.
"No desktops free in <pool>. Try again shortly"The pool is at Maximum desktops and none is being preparedRaise Maximum desktops if the nodes have memory. Desktops in Error count towards the maximum: delete them.
"Preparing your desktop…" for a long timeNo spare desktop; one is being preparedWatch the Desktops tab. The app keeps asking for 15 minutes. Raise Spare desktops or add a time-of-day rule for busy times.
"This desktop pool is switched off"The pool's Pool is on is offTurn it on in the pool editor.
"Desktop pools are unavailable right now. Try again shortly."The gateway can't reach sde-vdi: it's stopped or restarting, or the URL, secret or SDE_VDI_V1_NETWORKS don't matchdocker logs sde-gateway 2>&1 | grep "desktop pools". Readiness → Gateway has called sde-vdi. Launches during an sde-vdi restart fail this way; try again.
"Desktop pools aren't enabled on this gateway."SDE_VDI_URL or SDE_VDI_SECRET is missing in the gatewaySet both and restart the gateway.
"Couldn't confirm who you are. Sign out and in again."The gateway couldn't read the user from their Guacamole sessionSign out of SDE Remote and in again.
Linux pool: FreeRDP closes at onceRDP security is NLA, which xrdp doesn't supportSet it to TLS.

7. Guacamole-only accounts refused

Accounts listed in the gateway's SDE_LOCAL_ACCOUNTS (by default guacadmin) exist only in Guacamole. They can sign in to SDE Remote, but Windows doesn't know them, so their sign-in can't open a domain desktop.

  • The gateway tells sde-vdi when such a user asks for a pool, and sde-vdi refuses before handing out a desktop: "<user> is an SDE-only account, so it can't sign in to the desktops in <pool>. Sign in to SDE Remote with your domain account." The gateway logs AUDIT vdi-authorize REFUSED … reason=guac_only.
  • Before this check (gateway 1.0.12 with sde-vdi 0.5.8), such a launch took a spare desktop, failed with "Windows refused the sign-in", and held the desktop for the 3-minute sign-in grace before it was deleted and rebuilt. Other users could be left with nothing to use for several minutes.
  • Pools with Users sign in on the desktop ticked still accept these accounts, because the user signs in on the desktop with an account it knows.

Fix: sign in to SDE Remote with a domain account. If an account wrongly appears as Guacamole-only, take it out of SDE_LOCAL_ACCOUNTS and restart the gateway.

8. Desktops recycled too soon or too late

SymptomCauseFix
A desktop is deleted about 3 minutes after a launch where nobody signed inThe sign-in grace. FreeRDP closed (a refused sign-in, or the user closed the window at the sign-in prompt), so the app stopped checking in. After 3 minutes with nobody signed in, sde-vdi ends the lease (Activity: Lease ended, reason=logged-off held=3m…) and rebuilds the desktop.Fix the sign-in problem (section 6). Every failed launch costs one desktop rebuild, so keep enough spares while you investigate.
A user's desktop is gone after a breakThey disconnected without signing out, and Disconnected session kept for (default 30 min) passed, or the Group Policy disconnected-session limit signed them outRaise Disconnected session kept for, and the GPO limit with it, if users need longer.
A desktop is recycled while the user is workingMaximum session length (default 12 h) applies whatever the session is doingRaise it to 24 h if users work longer days.
A desktop stays In use after the user signed outSomeone is still signed in (for example an admin at the console), or FreeRDP is still open on the user's PC and the app keeps checking inCheck query user (2.1). Once nobody is signed in and the app has stopped, the desktop is recycled within a couple of minutes.
A user gets the same desktop againBy design: while their lease is live, the same user always gets the same desktop backNothing to fix. Delete now ends the lease if you need a fresh desktop for them.
SymptomCauseFix
Readiness: Sign in to AD as the join account fails after a DC went downsde-vdi finds a DC through DNS once, when it starts, and keeps using itSet SDE_VDI_AD_LDAP_HOST to a DC that's up, or restart sde-vdi once the DNS records are current.
Readiness: Sign in to AD as the join account failsWrong join password, or no LDAPS (636) from the gateway host to the DCCheck SDE_VDI_AD_USER and SDE_VDI_AD_PASS. Set SDE_VDI_AD_LDAP_HOST if the domain name doesn't resolve on the host.
Readiness: DC clock failsThe DC is more than 4 minutes out from sde-vdi; Kerberos fails at 5Fix the PDC's NTP source. On Proxmox, give the DC VM a Windows OS type.
Readiness: Domain join configured failsA pool has an OU, but SDE_VDI_AD_* isn't setAdd the lines printed by ad-bootstrap-sde-vdi.ps1 to the unit and restart it.
Old computer objects pile up in the OUNames that won't come back (the pool shrank, its pattern or OU changed, or it was deleted)Readiness → Active Directory clean-up → Scan for stale computer objects, tick, Delete selected….
Readiness: a Token privileges, Storage or Network line failsThe Proxmox token lacks a privilegeRun pve-bootstrap-sde-vdi.sh --check on a node; the Readiness line gives the command.
Clones are slow or the host strugglesToo many clones at once, or full clonesLower SDE_VDI_MAX_PARALLEL_CLONES (default 2) and use linked clones.

person people found this useful.