Skip to content
WindowsDeep Dive Published Updated 9 min readViews unavailable

Windows SPN Operations: Find Duplicate Kerberos Names and Assign Ownership Safely

Diagnose Windows Kerberos SPN failures by querying exact service names, finding duplicate ownership, validating tickets, and changing registrations safely.

A Service Principal Name (SPN) maps a service instance to the Active Directory account whose secret protects that service’s Kerberos tickets. If a client requests a ticket for HTTP/app.contoso.com, the domain controller must find a unique, correct owner. A missing SPN can prevent Kerberos from obtaining the expected service ticket; a duplicate can make ownership ambiguous; and an SPN on the wrong account can cause the service to fail to decrypt the ticket or encourage a fallback to another authentication protocol. These symptoms are often reported as generic “access denied,” delegation, or authentication failures.

An SPN repair is an identity change, not a text cleanup. Before adding, deleting, or moving one, establish the exact name clients request, which account the service runs as, which aliases or ports are in use, and whether delegation depends on the current registration. This procedure uses read-only queries first, reserves the state-changing setspn commands for an approved change, and ends with a real client-side Kerberos test. Do not remove every duplicate automatically or move registrations based only on a server rename.

Understand the name-to-account relationship

The SPN syntax is commonly serviceclass/host with optional port or service-name components. Examples include HTTP/web01.contoso.com, MSSQLSvc/sql01.contoso.com:1433, or a service-specific form documented by the application vendor. The correct value depends on the protocol and the exact name the client uses. A DNS alias can require its own SPN even when it resolves to the same IP address as a host name. Conversely, adding every DNS alias to every account can create collisions and obscure ownership.

The account that owns the SPN must correspond to the identity whose key the server-side service uses. A Windows service running as a gMSA needs its service SPN on that gMSA; an application running under a computer account may use the computer object; and a service running as a domain user may require the user object. Do not infer the right account from the server name alone. Check the service configuration, application pool identity, vendor documentation, cluster identity design, and any Kerberos constrained delegation configuration.

Kerberos is a chain of evidence. The client resolves the requested service name, obtains a ticket-granting ticket, requests a service ticket for the exact SPN, and presents it to the service. The service must be able to decrypt it with the key belonging to the SPN owner. DNS success does not prove SPN correctness; an SPN query does not prove that a service accepted a ticket; and successful access does not prove Kerberos was used if NTLM fallback is permitted. Capture client, server, domain controller, timestamp, account, exact URL or connection string, and authentication package before changing state.

Search for existing owners and duplicates

Start from an elevated administrative shell with the setspn tools available. Use the exact SPN form that the application requests. A forest-wide query is useful when service accounts or hosts cross domain boundaries; a local-domain query can otherwise miss an owner elsewhere in the forest.

$spn = 'HTTP/app.contoso.com'

# Read-only: list the current owner in the forest.
setspn.exe -F -Q $spn

# Read-only: list duplicate SPNs detected in the forest.
setspn.exe -F -X

# Read-only: inspect the intended account's current SPN set.
setspn.exe -L 'CONTOSO\gmsa-app01$'

-Q answers where the exact value is registered; -X searches for duplicate SPNs; and -L lists the SPNs on one account. Record the distinguished name or account name returned and compare it with the actual service identity. A forest-wide duplicate scan can be expensive in a large directory, so run it with appropriate permissions and at a sensible time. For focused diagnosis, query a single SPN rather than treating the entire directory as an unbounded search problem.

Inspect the service’s effective identity, not just a configuration file. For a Windows service, Get-CimInstance Win32_Service can show StartName; for IIS, inspect the application pool identity; for SQL Server, identify the engine and listener names; and for a cluster, identify the service identity that owns client connections. Correlate the host’s system log and Security-Kerberos events with the client result. Event IDs vary by failure and system role, so use the event’s provider, status code, requested target name, and account rather than matching one number without context.

Pay attention to name normalization. Clients may request a short host name while administrators search only the FQDN. A client may use a DNS alias, virtual name, load balancer name, CNAME, listener, or non-default port. Some clients construct SPNs differently depending on driver and connection options. Use a packet trace or application diagnostics where necessary to establish the exact target principal instead of guessing from DNS records. Consider IPv6, suffix search, and canonicalization behavior only where the client implementation makes them relevant.

Add or remove only an approved registration

When the intended owner is known and the SPN is not already present on a different valid account, use setspn -S for an addition. Its duplicate check is a valuable guardrail. Use a writable domain controller selected under change control and allow the resulting directory change to replicate before testing across sites.

$account = 'CONTOSO\gmsa-app01$'
$spn = 'HTTP/app.contoso.com'

# State-changing: use only after confirming account ownership and approval.
setspn.exe -S $spn $account

# Read-only verification after the change.
setspn.exe -F -Q $spn
setspn.exe -L $account

Do not use setspn -A as a substitute for the duplicate-aware -S form. Do not delete an SPN from the first account returned by a query. If an SPN exists on the wrong object, establish whether that object still hosts a service, whether an alias is shared, and whether another application depends on it. A duplicate may be a stale artifact, but it may also reveal that two live services were assigned the same client-facing name. Document the old owner and rollback plan before correcting it.

If an SPN must be removed, use the exact value and exact account, after verifying that the service no longer owns it:

# State-changing: remove only the verified obsolete registration.
setspn.exe -D 'HTTP/old-app.contoso.com' 'CONTOSO\legacy-app'

# Verify that the old value no longer has an owner.
setspn.exe -F -Q 'HTTP/old-app.contoso.com'

An SPN reassignment can affect service tickets already cached on clients and domain controllers. Allow for AD replication and ticket lifetimes. Do not purge tickets fleet-wide as a first response; that can disrupt unrelated authentication and obscure whether replication has converged. If a test client needs a fresh service ticket, schedule the test, capture the current ticket state, and purge only that test principal’s cache when the operational effect is understood.

Validate ticket issuance and service acceptance

After the directory change has replicated, test from a representative client using the production protocol and exact alias. Request the service ticket explicitly, then inspect the ticket cache:

# Run on a controlled client as the affected test identity.
klist.exe get HTTP/app.contoso.com
klist.exe

The get request proves that a service ticket could be issued for the requested principal from that client’s current domain context. It does not prove that the server can decrypt or accept the ticket, that the application authorizes the user, or that the connection used the expected endpoint. Complete an application-level request and inspect the server’s authentication telemetry. Confirm the negotiated package is Kerberos and check that the server process runs as the SPN owner. If the ticket is issued but the application reports a target-principal or integrity failure, investigate key ownership, service identity changes, machine-account password state, replication, and service restart timing.

For a multihomed service or load-balanced farm, repeat validation against each backend while preserving the client-facing name. Every node must use the same intended service identity or an explicitly supported per-node SPN design. If nodes use different keys while presenting the same SPN, ticket decryption can fail intermittently depending on which backend handles the request. For SQL Server, include the actual client driver, listener name, instance/port, and integrated-authentication option. For HTTP, test the URL including host header and TLS endpoint; TLS certificate identity is related to, but independent of, Kerberos SPN ownership.

Diagnose common patterns without masking them

If setspn -Q returns no owner, verify that the searched string exactly matches what the client requested. Check aliases and ports, account naming, and domain/forest scope before creating a new entry. If -X reports duplicates, map every result to a live service and its actual run-as account. If one host works and another fails, compare AD site, DC selection, replication, service identity, DNS resolution, and cached tickets. If failures begin after a service-account rotation, confirm that the SPN did not remain on the old account and that every server is running with the current identity.

If ticket issuance succeeds but application access fails, treat authorization and service decryption as distinct layers. Review the user’s group membership, application ACLs, delegation configuration, and service logs. If a service is expected to delegate to a backend, an SPN alone is not permission to delegate; constrained delegation must be explicitly configured for the correct front-end identity and allowed target services. Avoid enabling unconstrained delegation as a quick fix. For cross-domain scenarios, document trust direction, name suffix routing, and where the target SPN is registered.

Change control and lifecycle

Maintain an SPN inventory for service aliases, owner accounts, service owners, dependent clients, ports, and retirement dates. Include cluster and disaster-recovery identities. During a host rename or migration, compare current and target SPNs before cutover, add registrations only when the service is ready, and remove obsolete ones only after traffic has drained and rollback is no longer required. Use a canary request before broad client testing. Preserve command output and relevant event records as change evidence.

The acceptance condition is not “the command succeeded.” It is that the exact client-facing SPN has one intended owner; the owner matches the service’s effective cryptographic identity; domain replication is healthy; a controlled client obtains a ticket for the expected name; the service accepts it; and the application authorizes the operation. Re-run the duplicate and ownership checks after service migrations, identity rotations, DNS alias changes, and cluster failovers.

Related:

Sources:

Comments