0X000021C2

Fix ERROR_DS_HIGH_DSA_VERSION (0x21C2) — Can't Lower Domain Functional Level

You're trying to lower a domain or forest functional level and Windows Server refuses with 0x21C2. Here's the real fix and why it happens.

You just demoted or rebuilt a domain controller, tried to drop the domain functional level back down, and Windows Server slapped you with ERROR_DS_HIGH_DSA_VERSION (0x000021C2): The functional level of the domain (or forest) cannot be lowered to the requested value. Annoying, and honestly the error message doesn't tell you which DC is blocking you.

Here's the short version: at least one domain controller in the domain is still running at a higher functional level than the one you're trying to set. That's it. AD won't let you lower the floor below the highest DC in the room.

The fix: find the offending DC and get it out of the way

You need to identify every DC whose reported functional level is higher than your target, then either demote it, rebuild it at the lower OS level, or just accept the higher functional level and move on. Most of the time the culprit is a DC you demoted in the console but never actually cleaned up in AD.

  1. Open an elevated PowerShell on a DC or a machine with RSAT. You want the AD module loaded.
  2. List every DC in the domain and its OS version. Run this:
Get-ADDomainController -Filter * |
  Select-Object Name, OperatingSystem, OperatingSystemVersion, Site, HostName |
  Sort-Object OperatingSystemVersion -Descending |
  Format-Table -AutoSize

After that runs, you should see a table. Look at the OperatingSystemVersion column. Anything showing 10.0 (20348) is Server 2022, 10.0 (17763) is Server 2019, 6.3 (9600) is 2012 R2, and so on. Whichever DC is at the highest number is the one holding your functional level up.

  1. Check for lingering DCs that don't show up in the list. Demoted-but-not-cleaned-up DCs are the #1 cause of 0x21C2. Run:
Get-ADObject -LDAPFilter "(objectClass=computer)(userAccountControl:1.2.840.113556.1.4.803:=8192)" `
  -SearchBase (Get-ADDomain).DistinguishedName `
  -Properties operatingSystem, operatingSystemVersion |
  Select-Object Name, operatingSystem, operatingSystemVersion, DistinguishedName

The 8192 bit flag is SERVER_TRUST_ACCOUNT — that's how you spot stale DC computer accounts that AD still thinks are domain controllers. If you see a name in here that isn't in the first list, that's your ghost.

  1. Clean up the metadata for any ghost DC. On a healthy DC, run:
ntdsutil
metadata cleanup
connections
connect to server <HealthyDCName>
quit
select operation target
list domains
select domain <DomainNumber>
list sites
select site <SiteNumber>
list servers in site
select server <ServerNumber>
quit
remove selected server
quit
quit

You should see "Transferring / Seizing FSMO roles…" or "removed selected server" near the end. If it says "the selected server is not a DC", you can skip it — that one's already clean.

  1. Wait for replication, then retry the functional level change. On a DC that holds the PDC Emulator role, run:
Set-ADDomainMode -Identity contoso.com -DomainMode Windows2012R2Domain

Swap contoso.com for your domain and Windows2012R2Domain for whatever level you want. Valid values are Windows2008R2Domain, Windows2012Domain, Windows2012R2Domain, Windows2016Domain, and WindowsThresholdDomain (that last one is 2025 / preview). For forest level, it's Set-ADForestMode with the same value names.

If it works, you'll get no output. That's the boring success case. If you get 0x21C2 again, jump to the variations section below — the ghost DC wasn't the only one.

Why this works

Functional levels aren't a cosmetic setting. They gate which AD features the whole domain can use — things like the Recycle Bin, Authentication Policies, and Kerberos armoring. The rule Microsoft baked into the directory is simple: the reported level can never be lower than the lowest-level capability any live DC depends on. If a Server 2019 DC is still hanging around, you can't claim the domain is at 2012 R2, because that 2019 box may be using features 2012 R2 doesn't know about.

When you demote a DC with dcpromo or Uninstall-ADDSDomainController, AD strips its DC-ness but sometimes leaves the computer object and NTDS Settings metadata behind — especially if the demote was forced, or the machine had RODC role, or you killed it mid-flight. That leftover object still advertises a msDS-Behavior-Version value. Lower your target below that value and the KCC refuses the write with 0x21C2. Cleaning up the metadata removes the stale advertisement, and the level drops cleanly.

Less common variations

  • You're trying to lower the forest level, not the domain level. Forest level requires every domain in the forest to be at or below the target. If you have a child domain running Server 2019, you can't take the forest back to 2012 R2. Check each domain with Get-ADDomain -Server <childDC>.
  • You have a lingering RODC. Read-only DCs sometimes flip their behavior version back up after a replica sync. Check each RODC's msDS-Behavior-Version directly:
Get-ADObject -LDAPFilter "(objectClass=domainDNS)" -Properties msDS-Behavior-Version |
  Select-Object Name, msDS-Behavior-Version

Value mapping: 3 = 2008, 4 = 2008 R2, 5 = 2012, 6 = 2012 R2, 7 = 2016, 8 = 2025/preview. Anything above your target has to go.

  • You're seeing 0x21C2 right after restoring a system state backup. The restore can resurrect a DC metadata object that AD had already tombstoned. Re-run the metadata cleanup from step 4 and give replication a full cycle (usually 15 minutes, or force it with repadmin /syncall /AdeP).
  • You're trying to go below the base level installed during dcpromo. If you originally promoted this DC with Server 2016 media, you can't drop below Windows2016Domain. That's not a bug, it's a hard floor. Rebuild the domain if you really need to go lower.
  • Lingering hybrid Azure AD Connect objects. Rare, but a synced object with a manually edited msDS-Behavior-Version attribute (via ADSI Edit, usually from a botched schema extension) will trigger this. Check with ADSI Edit against the domain NC head and compare to the actual DC OS versions.

Prevention so you never see this again

Demote properly. Never unplug a DC or force the demote unless the box is dead. If it is dead, run metadata cleanup immediately afterward — don't let it sit for six months and surprise you during a functional level rollback.

Also, keep a written record of which DCs were promoted with which OS media. The functional level you can roll back to is capped by the lowest OS that was ever used to promote a DC in that domain. So if you've ever promoted a Server 2019 DC, you can never go below Windows2016Domain no matter how hard you try. Document it, tell your junior admins, and don't waste an afternoon chasing a limit that doesn't exist.

One more thing: before every functional level change — up or down — run repadmin /replsummary and dcdiag /q. If those come back clean and you've walked through the DC list above, 0x21C2 won't ever appear on your screen. If they don't come back clean, fix that first. Functional level changes on an unhealthy replication topology are how you turn a two-hour problem into a two-week one.

Related Errors in Windows Errors
0X0000085C Fix 0X0000085C: Internal Error on Windows Activation 0XC026232F Fix 0xC026232F: Invalid VidPN Target Subset Type Error on Windows 0XC0000103 STATUS_NOT_A_DIRECTORY (0xC0000103): Real Fixes That Work 0X000020DA Fixing ERROR_DS_GOVERNSID_MISSING (0X000020DA) Fast

Was this solution helpful?

EP
Erropedia Team
Tech Support Editors
The Erropedia editorial team researches and documents real-world tech errors from across Windows, Linux, macOS, networking, databases, cloud platforms, and more. Every solution is reviewed for accuracy and updated as software and systems evolve.