Duplicate SPN on a Computer Account (Most Common Cause)
This is what I see 80% of the time. Some service got installed, left an SPN behind on an old computer object, and when you try to register the same SPN on a new server — boom, error 0X000021C7. The real fix is finding and removing the duplicate.
Start by identifying the conflicting SPN. Open an elevated PowerShell or Command Prompt on any domain controller or domain-joined server with RSAT tools installed. Run:
setspn -X
This scans the entire forest and lists any duplicate SPNs. You'll see output like:
Checking forest CN=Configuration,DC=contoso,DC=com...
Duplicate SPN found: HTTP/webapp.contoso.com
CN=OLD-SERVER,CN=Computers,DC=contoso,DC=com
CN=NEW-SERVER,CN=Computers,DC=contoso,DC=com
Once you have the duplicate, delete the SPN from the wrong object. In this example, OLD-SERVER probably has the old one. Remove it with:
setspn -D HTTP/webapp.contoso.com OLD-SERVER
Then confirm the SPN is unique again with setspn -X. No need to restart anything — the fix takes effect immediately for new Kerberos tickets.
Don't bother checking DNS first, that's rarely the cause here. SPN uniqueness is purely an AD attribute issue.
Stale SPN on a Service Account (User Object)
Second scenario: someone registered an SPN on a domain user account meant for a service (like SQL Server or Exchange). Then they decommissioned the service but never cleaned up the SPN. When you try to register that same SPN on a machine account, the error hits.
Same approach — run setspn -X first. If the duplicate involves a user object, you'll see something like:
Duplicate SPN found: MSSQLSvc/sql01.contoso.com:1433
CN=SQLSvcAccount,CN=Users,DC=contoso,DC=com
CN=SQL01,CN=Computers,DC=contoso,DC=com
The user account SQLSvcAccount is the stale one. Remove it:
setspn -D MSSQLSvc/sql01.contoso.com:1433 CONTOSO\SQLSvcAccount
Pro tip: if you're not sure which object should keep the SPN, check the service bindings. For SQL, look at the SQL Server Configuration Manager — the service runs under a local system or a domain account. The SPN should match that account. Same for IIS, Exchange, etc.
I've seen admins accidentally register SPNs on service accounts during installations that prompt for SPN registration. Always double-check what account the SPN lands on.
SPN Registered on a Deleted but Not Tombstoned Object
This one's trickier. You delete a computer or user object with an SPN, but the AD garbage collection hasn't run yet. The SPN still exists in the forest's SPN index. Trying to register it again gives you 0X000021C7, even though you can't see the object in ADUC.
How to spot this: setspn -X might show the duplicate but only list one live object. The other half of the duplicate points to a deleted object. Use ADSI Edit or PowerShell to check the Deleted Objects container.
Connect to the Deleted Objects container in ADSI Edit:
- Open ADSI Edit.
- Right-click ADSI Edit, choose Connect to.
- Select Configuration in the well-known naming contexts, then check Advanced.
- Browse to
CN=Deleted Objects,DC=contoso,DC=com. - Look for the object name that matches the duplicate SPN.
If it's there, you have two options: wait for AD tombstone lifetime (default 180 days) to expire, or force removal with ntdsutil. I don't recommend the latter unless you're confident — it's a one-way door. Instead, just wait or, if urgent, create a new SPN with a slightly different name (like adding a port number) and update your service bindings.
I had this exact issue with an Exchange 2016 migration — old server was decommissioned but not forcefully removed from AD. Had to wait 48 hours for replication and GC to settle.
Quick-Reference Summary Table
| Cause | How to Identify | Fix |
|---|---|---|
| Duplicate on computer account | setspn -X shows two computer objects | setspn -D on the stale one |
| Duplicate on user account | setspn -X shows a user + computer object | setspn -D on the user object |
| Deleted but tombstoned object | setspn -X shows one live object, other half missing | Wait for tombstone or rename SPN |
Bottom line: always run setspn -X before you do anything else. That single command saves more time than any other debug step. If you don't find duplicates there, check your application logs — you might be dealing with a service that generates dynamic SPNs (like some third-party apps). In that case, set HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\YourService\Parameters\DisableDynamicSPN to 1 and register a static SPN manually.