setspn reads, adds, and deletes Service Principal Names (SPNs) on Active Directory accounts. An SPN is the identifier Kerberos uses to match a service — a SQL instance, an IIS app pool, a file share — to the account that runs it. When the SPN is missing, wrong, or duplicated, Kerberos authentication quietly falls back to NTLM or fails outright, and the symptoms are rarely obvious.
Most sysadmins meet setspn for the first time while chasing a “SQL connection uses NTLM instead of Kerberos” ticket or an intermittent authentication failure. This article focuses on the two problems the official docs barely mention: finding and resolving duplicate SPNs, and understanding why SPN accounts are a security exposure. The read-only queries here are safe to run in any domain; the modifying commands are clearly marked.
Applies to: Windows Server 2016 / 2019 / 2022 — and Windows 10 / 11 with RSAT installed.
Quick Answer
List every SPN registered to an account:
setspn -L corp\svc-sql
Search the whole forest for duplicate SPNs — the most common cause of intermittent Kerberos failures:
setspn -F -X
Both run from an elevated prompt. Reading SPNs works for any authenticated user; adding or deleting them requires write access to the account.
What setspn does
setspn edits the servicePrincipalName attribute on a user or computer object in Active Directory. It does not touch the service itself — it only tells the directory which account owns which service identity, so the KDC can hand out the correct Kerberos ticket.
An SPN follows the format serviceclass/host:port, for example MSSQLSvc/SRV-SQL-01.corp.local:1433 or HTTP/intranet.corp.local. The general syntax is:
setspn [switch] [SPN] [accountname]
The switches you actually use:
| Switch | Purpose | Changes AD? |
|---|---|---|
-L | List SPNs on an account | No |
-Q | Query who owns a specific SPN | No |
-X | Find duplicate SPNs | No |
-F | Run the query at forest level (use with -Q, -X, -S) | No |
-S | Add an SPN after checking for duplicates | Yes |
-A | Add an SPN without a duplicate check (legacy — avoid) | Yes |
-D | Delete an SPN | Yes |
-R | Reset an account’s default HOST SPNs | Yes |
setspn ships with the AD DS tools on Windows Server and with RSAT on Windows 10 / 11. Run it from an elevated command prompt — without elevation, the modifying switches return access-denied even for a Domain Admin.
Practical examples
1. List the SPNs on a service account
The problem: Applications connecting to a SQL instance are authenticating with NTLM instead of Kerberos, and you suspect the SQL service account is missing its SPN.
The solution: setspn -L shows exactly which SPNs are registered to the account, so you can confirm whether the expected MSSQLSvc entry is present.
setspn -L corp\svc-sql
Expected output for a correctly configured SQL account:
Registered ServicePrincipalNames for CN=svc-sql,OU=Service Accounts,DC=corp,DC=local:
MSSQLSvc/SRV-SQL-01.corp.local:1433
MSSQLSvc/SRV-SQL-01.corp.local
If that MSSQLSvc line is missing, Kerberos has no way to map the service to this account — which explains the NTLM fallback.
2. Find duplicate SPNs across the domain and forest
The problem: Authentication to a service “sometimes works.” It succeeds for some users or sessions and fails for others, with no clear pattern. This is the classic signature of a duplicate SPN.
The solution: setspn -X scans for any SPN registered on more than one account. Add -F to extend the search across the whole forest, since SPNs must be unique forest-wide for Kerberos to resolve them.
setspn -X -P
setspn -F -X -P
The -P switch suppresses the per-entry progress lines, which keeps the output readable and makes it easier to pipe into findstr. A duplicate looks like this:
Checking domain DC=corp,DC=local
MSSQLSvc/SRV-SQL-01.corp.local:1433 is registered on these accounts:
CN=svc-sql,OU=Service Accounts,DC=corp,DC=local
CN=svc-sql-old,OU=Service Accounts,DC=corp,DC=local
found 1 group of duplicate SPNs.
setspn -X without -F only checks the current domain. In a multi-domain forest it will miss a duplicate that lives in a sibling domain. Always run the -F version before concluding an SPN is unique.
3. Query who owns a specific SPN
The problem: Before adding an SPN, you need to know whether it already exists somewhere — and on which account — so you don’t create a duplicate or overwrite a working configuration.
The solution: setspn -Q checks a single SPN and reports the account that holds it, if any.
setspn -F -Q MSSQLSvc/SRV-SQL-01.corp.local:1433
If the SPN exists, the account is returned and the last line confirms it:
Checking forest DC=corp,DC=local
CN=svc-sql,OU=Service Accounts,DC=corp,DC=local
MSSQLSvc/SRV-SQL-01.corp.local:1433
Existing SPN found!
An empty result means the SPN is free to register.
4. Add an SPN safely
The problem: A new SQL instance on SRV-SQL-01 runs under corp\svc-sql, but no SPN was registered automatically, so Kerberos authentication is unavailable.
The solution: setspn -S adds the SPN only after verifying no duplicate exists — this is the switch you should always use to add SPNs.
rem Register both the port-specific and host-only SPN for the SQL account
rem -S checks for duplicates first, then writes the SPN if it is unique
setspn -S MSSQLSvc/SRV-SQL-01.corp.local:1433 corp\svc-sql
setspn -S MSSQLSvc/SRV-SQL-01.corp.local corp\svc-sql
A successful registration ends with Updated object:
Checking domain DC=corp,DC=local
Registering ServicePrincipalNames for CN=svc-sql,OU=Service Accounts,DC=corp,DC=local
MSSQLSvc/SRV-SQL-01.corp.local:1433
Updated object
servicePrincipalName attribute on the target account. This is a Domain Admin right by default, or a delegated permission. Run these commands from an elevated prompt.
5. Delete a stale or wrong SPN
The problem: A duplicate SPN was found in example 2 — an old, decommissioned account corp\svc-sql-old still holds the SPN that now belongs to corp\svc-sql. The duplicate must be removed from the wrong account.
The solution: setspn -D removes a single SPN from a specific account. Delete it from the account that should not hold it, leaving the correct owner intact.
rem Remove the duplicate from the OLD account only
rem The correct account (corp\svc-sql) keeps its SPN
setspn -D MSSQLSvc/SRV-SQL-01.corp.local:1433 corp\svc-sql-old
setspn has no undo. Deleting the SPN from the wrong account — or mistyping the SPN string — silently breaks Kerberos authentication for that service until you re-add it. Run setspn -F -Q first to confirm exactly which account you are deleting from.
6. Reset default HOST SPNs after a rename
The problem: A file server was renamed from SRV-FILE-OLD to SRV-FILE-01. File-share access over Kerberos now fails because the computer account still advertises the old HOST SPNs.
The solution: setspn -R resets the account’s default HOST SPNs to match its current name. This fixes the automatically managed SPNs (HOST-based services like CIFS and file access) without touching custom service SPNs.
rem Reset the default HOST SPNs on the computer account to its current name
setspn -R SRV-FILE-01
Registering ServicePrincipalNames for CN=SRV-FILE-01,OU=Servers,DC=corp,DC=local
HOST/SRV-FILE-01
HOST/SRV-FILE-01.corp.local
Updated object
-R only fixes the default HOST SPNs. Custom SPNs added for specific services — MSSQLSvc, HTTP, and similar — still have to be deleted with -D and re-added with -S under the new name.
Hidden gems
-A skips the very check that keeps you safe
Older guides and scripts use setspn -A to add an SPN. It works, but it writes the SPN without checking for duplicates — which is exactly how duplicate SPNs get created in the first place. There is no reason to use -A today. Use -S, which does the same thing but verifies uniqueness first.
“Works sometimes” almost always means a duplicate SPN
When an SPN is registered on two accounts, the KDC cannot decide which one to trust, so it may refuse to issue a ticket or issue one encrypted with the wrong account’s key. The result is authentication that succeeds and fails unpredictably. If a Kerberos issue is intermittent rather than constant, run setspn -F -X before anything else.
Every SPN account is a Kerberoasting target
Any authenticated user can request a Kerberos service ticket for any account that has an SPN. That ticket is encrypted with the service account’s password hash, which an attacker can then crack offline. The same command that helps you audit also helps an attacker enumerate targets:
rem List every account in the domain that has an SPN registered
setspn -T corp.local -Q */*
Computer accounts get HOST SPNs for free
When a machine joins the domain it automatically registers HOST/name and HOST/name.fqdn. The HOST SPN maps to many service classes behind the scenes (CIFS, file access, WSMAN, and others), so for services running as the machine’s own computer account you usually do not need to add SPNs manually — the HOST mapping already covers them.
PowerShell equivalents
For reading SPNs, the ActiveDirectory module works well and returns clean, scriptable objects. Read the SPNs on a computer account:
# Return the servicePrincipalName values as plain strings
Get-ADComputer SRV-SQL-01 -Properties servicePrincipalName |
Select-Object -ExpandProperty servicePrincipalName
Read the SPNs on a service (user) account:
# Same idea for a user-based service account
Get-ADUser svc-sql -Properties servicePrincipalName |
Select-Object -ExpandProperty servicePrincipalName
setspn -X is still the fastest way to find duplicate SPNs — there is no single built-in cmdlet that does the same forest-wide duplicate scan in one line. Many admins read with PowerShell and fix with setspn.
Where this matters
SQL Server Kerberos — a missing or wrong MSSQLSvc SPN forces clients to NTLM and breaks double-hop delegation scenarios like linked servers and Reporting Services.
IIS and web application SSO — Kerberos single sign-on to an intranet site depends on the correct HTTP SPN being registered on the app pool identity, not on the machine.
After a server rename — old SPNs still point at the previous hostname; resetting HOST SPNs and re-registering service SPNs restores Kerberos access.
Intermittent authentication failures — a duplicate SPN across two accounts produces the “works for some, fails for others” pattern that is hard to diagnose any other way.
Security and audit reviews — enumerating SPN-enabled accounts reveals which service accounts are exposed to Kerberoasting and need stronger passwords or a move to gMSA.
Tips and limitations
- Reading SPNs (
-L,-Q,-X) is available to any authenticated user. Adding, deleting, or resetting requires write access toservicePrincipalName— Domain Admin by default or a delegated right. - Always run
setspnfrom an elevated command prompt. Without elevation the modifying switches fail even with the correct permissions. - SPNs must be unique across the entire forest. A domain-only
-Xor-Qcan miss a cross-domain duplicate — use-Ffor anything conclusive. - There is no undo. Deleting the wrong SPN breaks authentication for that service until it is re-added, so query first.
- After changing SPNs, existing Kerberos tickets remain cached until they expire. Run
klist purgeon the client to test the change immediately instead of waiting.
Official documentation
Related tools
- nltest Command Builder — build the domain and secure-channel diagnostic commands you often run alongside SPN checks during a Kerberos investigation.
Related guides
- nltest command in Windows: domain controller discovery and trust diagnostics — when SPN checks come up clean, nltest confirms the DC and secure channel behind the authentication.
- dsquery and dsget in Windows: command-line Active Directory queries — locate and inspect the service accounts you register SPNs on.
- DCDiag: how to diagnose and fix Active Directory problems — rules out DC health and Kerberos time-sync issues that mimic SPN failures.
- How to fix “trust relationship between this workstation and the primary domain failed” — the related secure-channel failure that also breaks domain authentication.