A service desk playbook for gMSA and dMSA failures on Windows Server 2025: KDS root key setup, Test-ADServiceAccount False, Kerberos encryption mismatch, dMSA migration flow, and BadSuccessor mitigation.
Most Managed Service Account failures on Windows Server 2025 come down to four things: a missing or unreplicated KDS root key, the host not being in the group listed in PrincipalsAllowedToRetrieveManagedPassword, a Kerberos encryption mismatch between the account and the server, or a delegated Managed Service Account (dMSA) migration that was completed too fast. I run the service desk for a Windows-heavy environment, and honestly, these tickets have exploded since Server 2025 DCs started replacing our 2019 boxes. This guide walks through the exact PowerShell you need for gMSA installs, dMSA migrations, KDS root key recovery, and closing the BadSuccessor privilege-escalation hole that shipped in the default configuration.
Every domain needs exactly one KDS root key; without it every gMSA and dMSA cmdlet fails with Key does not exist.
Test-ADServiceAccount returning False almost always means the host is not in the group listed in PrincipalsAllowedToRetrieveManagedPassword, or a Kerberos ticket cache is stale (restart or run klist purge -li 0x3e7).
Windows Server 2025 defaults to AES-only (msDS-SupportedEncryptionTypes = 24); pre-existing gMSAs set to 28 (AES + RC4) will fail installation until you drop RC4.
Delegated Managed Service Accounts (dMSAs) supersede regular service accounts only. You cannot migrate an existing gMSA into a dMSA.
BadSuccessor (CVE-2025-53779) let non-admins escalate to Domain Admin via dMSA in the default configuration; patch DCs to build 26100.4946 or later and audit CreateChild rights on every OU.
Never complete a dMSA migration until at least two Kerberos ticket lifetimes (roughly 14 days) have passed since the Start-ADServiceAccountMigration call.
Fixing the KDS root key: the root cause of most gMSA failures
Every managed service account in the forest is protected by a Microsoft Key Distribution Service (KDS) root key. Without one, New-ADServiceAccount throws Key does not exist and Install-ADServiceAccount fails with an unspecified error. I've opened plenty of severity-2 tickets from a junior engineer who assumed a fresh domain would have this configured. It does not. You add it once per forest, on a DC, running as a member of Enterprise Admins or Domain Admins in the forest root.
The safe production command adds the key with the default effective time. Microsoft holds the key inactive for ten hours to give AD replication time to converge before any gMSA tries to retrieve a password. It's a safety belt I've never regretted in production:
# Run on a writable Windows Server 2019/2022/2025 domain controller
# Requires Enterprise Admins in the forest root domain
Add-KdsRootKey -EffectiveImmediately
# Verify the key exists and note the KeyId
Get-KdsRootKey | Format-List KeyId, EffectiveTime, CreationTime
In a lab where you can't wait ten hours, use the well-known back-date. Do not ever run this in production. The moment two DCs disagree on the key, you'll chase ghost failures for weeks:
# LAB ONLY. Effective time is set ten hours in the past
# so the key is immediately usable on this single DC.
Add-KdsRootKey -EffectiveTime ((Get-Date).AddHours(-10))
If Add-KdsRootKey throws HRESULT 0x80070020, The process cannot access the file because it is being used by another process, the DC is almost certainly living outside the built-in Domain Controllers OU. Move it back with Move-ADObject, wait for replication, and rerun. The Microsoft Create the KDS root key guidance covers the forest-level requirements in detail. For the aftermath of a Golden gMSA compromise, follow the official recovery playbook. Don't just delete and recreate the key, or every existing gMSA becomes unusable until it rolls its password.
Why is Test-ADServiceAccount returning False?
Test-ADServiceAccount returns False when the local machine can't retrieve the gMSA's managed password. That's a permissions and ticketing problem, not an account problem, and it usually means one of five things: the machine is not a member of the group in PrincipalsAllowedToRetrieveManagedPassword, the machine's Kerberos ticket still reflects its old group memberships, the KDS root key has not replicated yet, the account was linked to a different computer as a legacy standalone MSA, or a Kerberos encryption type is missing. The MSA operational log at Applications and Services Logs → Microsoft → Windows → Security-Netlogon is the fast confirmation.
Here's the tier-1 diagnostic block I've pinned to our internal wiki. Every line is commented so a first-week engineer can run it without paging me:
# --- gMSA readiness triage. Run ON THE MEMBER SERVER, not the DC ---
# 1. Confirm the ActiveDirectory PS module is present (comes with RSAT)
Import-Module ActiveDirectory -ErrorAction Stop
# 2. Does this box actually pass the readiness check?
Test-ADServiceAccount -Identity 'gmsa-sqlprod'
# 3. Which principals are allowed to retrieve the password?
Get-ADServiceAccount 'gmsa-sqlprod' -Properties `
PrincipalsAllowedToRetrieveManagedPassword,
msDS-SupportedEncryptionTypes |
Format-List Name, PrincipalsAllowed*, msDS-SupportedEncryptionTypes
# 4. What groups does THIS COMPUTER account currently think it is in?
# LocalSystem SID is S-1-5-18 -> logon session 0x3e7
klist -li 0x3e7
# 5. Purge stale Kerberos tickets for LocalSystem so the next AS-REQ
# reflects the new group membership from step 3.
klist purge -li 0x3e7
The classic mistake (and I hit this exact one on my first Server 2016 rollout) is putting the computer object directly into PrincipalsAllowedToRetrieveManagedPassword and adding a second server later without restarting. The second server never gets a fresh TGT with the group SID, so Test-ADServiceAccount stays False forever. Fix it by moving the permission to a global security group (gMSA-SQLProd-Hosts is the naming convention I use), adding both computers to that group, and purging tickets or restarting.
Install-ADServiceAccount errors and how to fix them
Install-ADServiceAccount is a local operation that caches the gMSA credential material in LSA on the member server. It cannot succeed until Test-ADServiceAccount returns True, which trips up engineers who work through the cmdlets in the wrong order. If Install-ADServiceAccount throws Cannot install service account. Error Message: An unspecified error has occurred, always go back to step 2 of the block above and fix the readiness check first.
The three remaining root causes I see on tickets are the account being a legacy standalone MSA already linked to a different computer, a corrupted managed password on the gMSA object itself, and a missing AD PowerShell module on the host. For the corrupted-password case, the fix is a one-liner on a DC followed by forced replication and a host restart:
# Run on a DC as Domain Admins
# Rotates the managed password immediately.
Reset-ADServiceAccountPassword -Identity 'gmsa-sqlprod'
# Force replication so every DC has the new password
repadmin /syncall /AdePq
# Then on the MEMBER SERVER:
# Restart, or use klist purge -li 0x3e7, then reinstall.
Install-ADServiceAccount -Identity 'gmsa-sqlprod'
Test-ADServiceAccount -Identity 'gmsa-sqlprod' # should now return True
Kerberos encryption mismatch on Windows Server 2025
Windows Server 2025 turns off RC4 for new gMSAs by default, and the domain controller's msDS-SupportedEncryptionTypes attribute reads 24 (AES128 + AES256). A gMSA created on a 2019 or 2022 DC often carries the legacy value 28 (AES128 + AES256 + RC4). When a Server 2025 host tries to install it, Test-ADServiceAccount returns False, the MSA operational log flags an encryption mismatch, and installation fails.
The safe fix is to drop RC4 on the gMSA object. The blast radius is zero as long as every host that consumes the account supports AES, which is every supported Windows version in 2026:
# Show the current encryption bitmap on the gMSA
# 8 = AES128_HMAC_SHA1
# 16 = AES256_HMAC_SHA1
# 24 = AES128 + AES256 (Server 2025 default)
# 28 = AES128 + AES256 + RC4 (legacy default, 4 = RC4)
Get-ADServiceAccount 'gmsa-sqlprod' `
-Properties msDS-SupportedEncryptionTypes |
Select-Object Name, msDS-SupportedEncryptionTypes
# Flip it to AES only:
Set-ADServiceAccount -Identity 'gmsa-sqlprod' `
-KerberosEncryptionType AES128,AES256
# On the host: purge and retest
klist purge -li 0x3e7
Test-ADServiceAccount -Identity 'gmsa-sqlprod'
My Kerberos troubleshooting guide covering the RC4 deprecation has the wider picture on which application vendors still ship 2010-era libraries that only negotiate RC4. If you find one, log a vendor ticket and pin that host to a legacy encryption GPO with a documented expiry date. Don't leave RC4 enabled forest-wide because one appliance is stuck on it.
How do I migrate a service account to a dMSA?
Delegated Managed Service Accounts arrived in Windows Server 2025 to solve the last mile that gMSAs did not: the plaintext password is machine-bound and never leaves the DC. Migration replaces a legacy service account (a normal user configured as Password never expires) with a dMSA that assumes the same SPNs and delegation settings, then disables the old account on cut-over. You need at least one Windows Server 2025 DC that is discoverable from the target host, and Domain Admins or equivalent delegated rights. Read the Microsoft Delegated Managed Service Accounts overview before you touch a production account.
# Prereqs on the DC running Server 2025:
# - KDS root key exists (Get-KdsRootKey)
# - The old service account is a normal user, NOT a gMSA
# 1. Create the dMSA and start the migration in one call.
Start-ADServiceAccountMigration `
-Identity 'CN=svc-sqlprod-dmsa,OU=Managed Service Accounts,DC=corp,DC=example,DC=com' `
-SupersededAccount 'CN=svc-sqlprod,OU=Service Accounts,DC=corp,DC=example,DC=com'
# 2. On EVERY host that runs the service, sign into the service
# interactively at least once using the OLD account.
# Each successful logon adds the host's computer account to
# the dMSA's groupMSAMembership. Two ticket lifetimes minimum.
# 3. Verify hosts have been enrolled:
Get-ADServiceAccount 'svc-sqlprod-dmsa' -Properties `
msDS-DelegatedMSAState, msDS-GroupMSAMembership
# 4. Cut over. Only when every host is listed.
Complete-ADServiceAccountMigration -Identity 'svc-sqlprod-dmsa'
Rush the cut-over, and services on any host that never got a fresh TGT will start failing with The user name or password is incorrect the moment the legacy account is disabled. If you have to abort, Undo-ADServiceAccountMigration puts the state back and re-enables the old account. Reset-ADServiceAccountMigration wipes the state machine so you can start over.
BadSuccessor: detecting and mitigating dMSA privilege escalation
BadSuccessor is the Akamai-disclosed dMSA abuse chain, tracked as CVE-2025-53779, that lets any principal with CreateChild on any OU forge a fake migration and inherit an arbitrary target user's SID, including Domain Admin and KRBTGT. Akamai's original BadSuccessor writeup found this default in 91% of the environments it audited. Microsoft's August 12, 2025 update (Server 2025 build 26100.4946) enforces server-side validation of the migration link, which kills the original attack. Post-patch, an additional attack path called BetterSuccessor still works if the attacker already has GenericWrite on the target principal, so patching alone isn't enough. Fixing this is a two-track effort: patch DCs and audit OU delegation.
Run this on your most-privileged DC to inventory who can create dMSAs anywhere in the domain. I generally file a change ticket to yank CreateChild for msDS-DelegatedManagedServiceAccount from anyone who isn't in Domain Admins:
# Enumerate non-default principals with CreateChild on any OU,
# focusing on msDS-DelegatedManagedServiceAccount object class.
# This is a simplified version of what Akamai and Semperis published.
$ouList = Get-ADOrganizationalUnit -Filter * -Properties nTSecurityDescriptor
$dmsaClassGuid = [Guid]'0feb936f-47b3-49f2-9386-1dedc2c23765' # msDS-DelegatedManagedServiceAccount
foreach ($ou in $ouList) {
foreach ($ace in $ou.nTSecurityDescriptor.Access) {
if ($ace.ActiveDirectoryRights -match 'CreateChild|GenericAll|GenericWrite|WriteDacl' -and
($ace.ObjectType -eq $dmsaClassGuid -or $ace.ObjectType -eq [Guid]::Empty)) {
# Filter out expected defaults such as Domain Admins / Enterprise Admins
if ($ace.IdentityReference -notmatch 'Domain Admins|Enterprise Admins|SYSTEM|BUILTIN\\Administrators') {
[PSCustomObject]@{
OU = $ou.DistinguishedName
Principal = $ace.IdentityReference
Rights = $ace.ActiveDirectoryRights
}
}
}
}
}
Turn on auditing for Directory Service Changes and watch for two signatures: Event ID 5136 flipping msDS-DelegatedMSAState to 2, and Event ID 4662 setting msDS-ManagedAccountPrecededByLink to a privileged target. If either fires outside a change window, treat it as a domain compromise until proven otherwise. My Active Directory account lockout guide lists the audit policy toggles you probably already have half-configured.
gMSA vs. dMSA: which one should you deploy?
Both remove humans from the password loop, but they solve different problems. gMSAs work on downlevel domains (Server 2012 R2 forest functional level and up), can be shared across many servers, and are trivial to deploy. That's why I still recommend them as the default for load-balanced application pools. dMSAs are the right pick when you need machine-bound credentials that survive a Credential Guard-hardened host and defeat Kerberoasting entirely, but they require a Server 2025 DC and are locked to a single host in most current deployments.
Dimension
gMSA (Group Managed Service Account)
dMSA (Delegated Managed Service Account)
Minimum forest functional level
Server 2012 R2
At least one Server 2025 DC
Runs on multiple hosts?
Yes, via PrincipalsAllowedToRetrieveManagedPassword
Typically one host per dMSA
Password location
Retrievable to any authorised host
Machine-bound; stays on the DC
Credential Guard integration
Partial
Full
Resistant to Kerberoasting
Yes (long random password)
Yes, and to credential dumping
Migration path from a user account
Manual reconfiguration
Start-ADServiceAccountMigration
Known privilege-escalation risk
Golden gMSA (limited, requires DC compromise)
BadSuccessor / BetterSuccessor
Cmdlet to install locally
Install-ADServiceAccount
Not required (machine binding is implicit)
My rule of thumb after six months of Server 2025 in production: gMSAs remain the default; dMSAs go on Tier-0 assets (backup services, PAM connectors, SQL instances holding secrets) and any host running Credential Guard. Never move a service to a dMSA without first inventorying which hosts touch it. The single-host binding will burn you if you missed a backup agent on a second box.
Service desk runbook: escalation ladder for MSA tickets
When a service that runs under a gMSA or dMSA starts failing at 03:00, the on-call engineer doesn't need theory. They need an ordered list. Here's the runbook I put in our GPO-managed runbook share so tier-1 doesn't wake me up unless something is actually on fire:
Confirm the account still exists, using Get-ADServiceAccount <name> -Server <nearest DC>. If it was deleted, restore from AD Recycle Bin; don't recreate it, or every dependent service loses its SPNs.
Verify readiness from the failing host with Test-ADServiceAccount. False? Jump to step 3. True? Jump to step 5.
Refresh Kerberos: klist purge -li 0x3e7, then re-test. Still False? Confirm the host is a member of the retrieval group and consider a restart.
Check encryption via Get-ADServiceAccount <name> -Properties msDS-SupportedEncryptionTypes. If it shows 28 on a Server 2025 host, drop RC4 with Set-ADServiceAccount -KerberosEncryptionType AES128,AES256.
Check SPNs with setspn -L <name>. A missing SPN causes Cannot generate SSPI context, not a Test failure.
For dMSA: check state using Get-ADServiceAccount <name> -Properties msDS-DelegatedMSAState. State 2 is migrated-complete; state 1 means the migration is still in progress and the OLD account is what the service is trying to use.
Rotate with Reset-ADServiceAccountPassword as a last resort, followed by repadmin /syncall /AdePq. This resolves the corrupted-password corner case but breaks any host with a stale ticket, so schedule it.
Anything past step 7 goes to the identity team. If you also need to unpick why domain controllers aren't converging on the change, my Active Directory replication troubleshooting walkthrough covers repadmin /replsummary and the usual USN rollback traps that block MSA password rollout.
Frequently Asked Questions
How long does the KDS root key take to replicate?
Microsoft holds a newly created KDS root key inactive for ten hours to give AD replication time to converge across every domain controller before any gMSA tries to retrieve a password. Trying to create a gMSA earlier throws Key does not exist. In labs you can back-date the effective time with Add-KdsRootKey -EffectiveTime ((Get-Date).AddHours(-10)), but never in production.
Can I migrate an existing gMSA to a dMSA?
No. Start-ADServiceAccountMigration supersedes only regular user-based service accounts. To move a workload from a gMSA to a dMSA you have to provision a new dMSA in parallel, reconfigure the service to use it, and decommission the old gMSA afterwards.
Do I need to restart after running Install-ADServiceAccount?
Usually no. The credential material lands in LSA immediately and services configured to use the account can pick it up. You do need to restart or run klist purge -li 0x3e7 if the host was just added to the retrieval group, because the Kerberos TGT will not yet contain the new group SID.
What is BadSuccessor and am I still vulnerable after the August 2025 patch?
BadSuccessor (CVE-2025-53779) let a principal with CreateChild on any OU forge a dMSA migration and inherit an arbitrary user's SID, including Domain Admin. Patched DCs (Server 2025 build 26100.4946 or later) block the original vector, but the BetterSuccessor variant still lets an attacker with GenericWrite on a target principal escalate. Patch and tighten OU delegation.
Why does Install-ADServiceAccount fail with "unspecified error"?
Almost always because Test-ADServiceAccount is returning False. Fix the readiness check first: verify the host is in the retrieval group, purge Kerberos tickets for LocalSystem (klist purge -li 0x3e7), and confirm the gMSA's msDS-SupportedEncryptionTypes attribute does not include RC4 if the host is Server 2025.
Which Kerberos encryption types should I set on a new gMSA in 2026?
AES128 and AES256 only. Server 2025 and current Windows 11 clients disable RC4 by default (msDS-SupportedEncryptionTypes = 24). Create accounts with -KerberosEncryptionType AES128,AES256 and leave RC4 (value 4) off unless a documented legacy appliance forces it, and if so, isolate it.
Troubleshoot Intune EPM in 2026: licensing, missing Run with elevated access menu, denied elevation requests, EpmService failures, and the Support Approvals workflow. PowerShell, log paths, and the Elevation report workflow that shrinks tier-1 tickets.
A helpdesk-first runbook for troubleshooting Microsoft Global Secure Access in 2026: GSA client Health Check, missing PRT, empty forwarding profiles, Entra Private Access connector faults, correlation vector log lookups, and the June 2026 v2.31.125 client changes.
A helpdesk-tested triage order for Windows 365 Cloud PC problems in 2026: gateway error 0x3000047, provisioning failures, Boot to Cloud PC, Flex shared mode, and when to Restart, Restore, or Reprovision without destroying user data.