Active Directory · Troubleshooting

Kerberos Authentication Fails — Duplicate SPN and KRB_AP_ERR_MODIFIED

When Kerberos logs a KRB_AP_ERR_MODIFIED error, the service ticket was encrypted with one account’s key and decrypted with another’s — nearly always because the same Service Principal Name is registered on two accounts, and the fix is to find the duplicate and remove it.

Quick idea: A Service Principal Name is the address Kerberos uses to encrypt a ticket for a specific service. If two accounts claim the same SPN, the KDC encrypts the ticket with one account’s password and the service tries to open it with the other’s — the keys do not match, and authentication fails. One SPN must belong to exactly one account.
SPN

Service Principal Name — e.g. HTTP/app.corp.example.com. Maps a service to the account that runs it.

Service ticket

Encrypted by the KDC with the target account’s key. Only that account can decrypt it.

KRB_AP_ERR_MODIFIED

The client’s proof that the key the service used does not match the key the ticket was sealed with.

Introduction

A web application, SQL connection, or file service that used integrated Windows authentication suddenly falls back to prompting for a password, or fails outright. Some users are fine; others hitting the same name are not. The application log or System log carries a Kerberos Event ID 4, and the phrase in it — KRB_AP_ERR_MODIFIED — sounds like something was tampered with.

Nothing was tampered with. The error is Kerberos being precise about a key mismatch, and the most frequent reason for that mismatch is mundane: someone registered the same SPN on a second account — often a service account and the computer account, or two service accounts — and now the KDC and the service disagree about which key to use. Find the duplicate, remove the wrong one, and it clears.

What You’re Seeing

The signature is Event ID 4 from source Kerberos. Its own text names the likely cause — identically keyed accounts — which is the clue that sends you to the SPN check:

Log Name:  System
Source:    Security-Kerberos
Event ID:  4
Level:     Error

The Kerberos client received a KRB_AP_ERR_MODIFIED error from the
server app01$. The target name used was HTTP/app.corp.example.com.
This indicates that the target server failed to decrypt the ticket
provided by the client. This can occur when the target server
principal name (SPN) is registered on an account other than the
account the target service is using. Ensure that the target SPN is
only registered on the account used by the server.
Key point: The event text tells you the resolution in its last sentence — “the target SPN is only registered on the account used by the server”. The whole investigation is confirming which accounts hold that SPN and making sure only the correct one does.

What It Actually Means

When a client wants to use a service, it asks the KDC for a ticket to that service’s SPN. The KDC finds the account that owns the SPN, encrypts the ticket with a key derived from that account’s password, and hands it back. The client presents the ticket to the service, and the service decrypts it with its own key. If the account the KDC used and the account the service actually runs as are different, the keys differ and decryption fails — that failure is KRB_AP_ERR_MODIFIED.

Two situations produce that split. In the first, the SPN is registered on the wrong single account — the service runs as svc-app but the SPN sits on the computer object. In the second, and more common, the SPN is registered twice — on both svc-app and the computer, or on two service accounts. The KDC picks one; the service uses the other. This connects to the identity fundamentals in the security basics post and the Kerberos flow in the authentication post.

In simple terms: Two mailboxes were labelled with the same name. The post office (the KDC) drops the letter in one; the reader checks the other and finds it empty. The letter is fine — the label is duplicated.

Step 1: Find Duplicate SPNs

The first command is the whole game. setspn -X scans the entire directory and lists every SPN that is registered on more than one account. If your failing SPN appears, you have your answer immediately.

# Scan the whole forest for duplicate SPNs - run this first
setspn -X

# Ask specifically which account(s) hold the failing SPN
setspn -Q HTTP/app.corp.example.com

# List every SPN registered on a given account
setspn -L svc-app
setspn -L app01
What to look for: setspn -X prints “found N group of duplicate SPNs” and names the accounts. If HTTP/app.corp.example.com is listed under both a service account and a computer object, that duplication is the fault. setspn -Q confirms it in isolation for the one name you care about.

Step 2: Identify the Correct Owner

Before deleting anything, establish which account the service actually runs as — that is the account that must keep the SPN. Check the service’s logon identity, and match it to the SPN owner.

# What identity does the service run under? (the SPN must live here)
Get-CimInstance Win32_Service -Filter "Name='w3svc'" |
    Select-Object Name, StartName

# Confirm the account and its current SPNs
setspn -L svc-app

# For app-pool / custom services, check the configured identity too
sc.exe qc <servicename>
Important: The SPN must be registered on the account the service logs on as. If the service runs as svc-app, the SPN belongs on svc-app — not on the computer object, and not on a second service account. Decide the correct owner first; only then remove the wrong registration.

Step 3: Remove the Duplicate

Delete the SPN from the account that should not have it, leaving it on the correct owner. Then verify the duplicate is gone.

# Remove the SPN from the WRONG account (here, the computer object)
setspn -D HTTP/app.corp.example.com app01

# Confirm the SPN now resolves to exactly one account
setspn -Q HTTP/app.corp.example.com

# Re-scan to confirm no duplicates remain
setspn -X
Production note: setspn -D is a directory change — removing the SPN from the correct account by mistake will break the working half of the service. Double-check the account name in the delete command against the service’s real logon identity before you run it. After the change, the affected clients may need to discard cached tickets (klist purge) or wait for ticket lifetime to expire.

Common Causes

KRB_AP_ERR_MODIFIED has a short list of causes. Duplicate and misplaced SPNs dominate; the rest are worth knowing so you do not misdiagnose.

Cause How to Confirm Fix
SPN registered on two accounts setspn -X lists the SPN as a duplicate group. setspn -D the SPN from the wrong account; keep it on the service’s logon account.
SPN on the wrong single account setspn -Q shows one owner, but not the account the service runs as. Delete from the wrong account and add to the correct one (setspn -S).
Service account changed, SPN not moved Service was switched to a new identity; SPN still on the old account or computer. Move the SPN to the new logon account.
Duplicate computer name / account Two machines share a name; both computer objects hold host SPNs. Rename or remove the stale duplicate computer object.
Machine password / secure channel out of sync Computer’s key differs from AD; nltest /sc_query fails. Repair the secure channel.
DNS name resolves to the wrong host Common with NLB or shared names; the name points at a different server than expected. Correct the DNS record; register the SPN on the account serving that name.
Time skew beyond five minutes Clock offset from the DC breaks ticket validation. w32tm /resync; fix the time source.

Working Through a Fix

The path is short because the cause usually is. Run setspn -X to reveal duplicates and setspn -Q <spn> to see who holds the failing name. Establish the service’s true logon identity, then setspn -D the SPN from every account that is not that identity. Re-run setspn -Q and confirm exactly one owner remains, and setspn -X to confirm the duplicate group is gone.

If setspn -X shows no duplicates at all, do not force the SPN theory — move to the other causes. Confirm the SPN sits on the account the service actually runs as, check the machine’s secure channel, verify the name resolves to the right host, and rule out time skew. KRB_AP_ERR_MODIFIED is a key mismatch; those are simply the other ways two keys can end up different.

Defence: After any change, purge cached tickets on an affected client with klist purge and retry, rather than concluding the fix failed while a stale ticket is still in play. Tickets outlive the directory change that invalidated them.

How to Prevent It

Duplicate SPNs are almost always self-inflicted during service setup. Register SPNs with setspn -S rather than setspn -A — the -S form checks for an existing duplicate and refuses to create a second one, which stops the problem at the source. Keep service identities deliberate: one service, one dedicated account, and the SPN on that account, so there is never ambiguity about who owns a name.

Build a periodic setspn -X into your AD hygiene checks so a duplicate introduced by a hurried install surfaces on a schedule instead of during an outage. And when you retire or re-purpose a service account, clean up its SPNs as part of decommissioning — orphaned and misplaced SPNs are what a later install collides with. Managed service accounts, which handle SPN registration for you, remove much of this risk entirely.

Quick Reference

Command Use
setspn -XScan the forest for duplicate SPNs. The first and best check.
setspn -Q <spn>Show which account(s) hold a specific SPN.
setspn -L <account>List every SPN on a given account.
setspn -D <spn> <account>Remove an SPN from an account (delete the duplicate).
setspn -S <spn> <account>Add an SPN with a duplicate check — use this instead of -A.
klist purgeDiscard cached tickets so a client picks up the corrected SPN.
Event 4 (Kerberos)KRB_AP_ERR_MODIFIED — the ticket key did not match the service key.

Final Thoughts

KRB_AP_ERR_MODIFIED is one of those errors whose name oversells the drama. Nothing was modified maliciously — Kerberos is simply reporting, correctly, that the key which sealed a ticket is not the key trying to open it. The overwhelmingly common reason is a Service Principal Name living on two accounts at once.

Run setspn -X, remove the duplicate from the account that should not hold it, purge tickets, and integrated authentication comes back. Register future SPNs with -S and give each service its own account, and the error stops recurring.

Key takeaway: Run setspn -X to find duplicate SPNs, and setspn -Q <spn> to see who owns the failing one. Remove it from the wrong account with setspn -D, leaving it only on the account the service logs on as, then klist purge on the client. Going forward, register SPNs with setspn -S so a duplicate can never be created.
More troubleshooting

Next: LDAP bind failures after enabling LDAP signing and channel binding — why legacy applications suddenly get “strong authentication required”, how to find them with Event 2889, and how to enforce safely.