SpnManager/decision-tree
Kerberos broken now? →
Kerberos failure decision tree

From "authentication is broken" to a probable cause.

Answer what you can see. Each leaf names the probable cause and the command that confirms it. Nothing here writes to AD.

path/ {{ p }}
{{ question }}
probable cause
{{ leaf }}
confirm with
{{ cmds }}

the whole tree, in text

Readable without JavaScript. Each node names where its answers lead.

start
What does the client see?
Cannot generate SSPI context → sspi · Works for some users, not others → some · Anonymous logon on the back end (double hop) → hop · Access denied or ticket errors after a password change → kvno · It works, but I need to know whether it is Kerberos → verify
sspi
Is the client connecting by FQDN, short name, or IP?
IP address → ip · FQDN or short name → name
ip
Clients connecting by IP bypass Kerberos. Reconnect by FQDN. If the symptom persists, continue with the name path.
Test-SpnPlan
name
Does the SPN exist on exactly one account?
I do not know → dup · On zero accounts → missing · On more than one → duplicate · On one account → which
dup
Run the forest-wide duplicate scan and the provider sense stage. One of them will answer this in a minute.
Invoke-SpnDuplicateScan Invoke-SpnLifecycle -ProviderId <provider> -WhatIf
missing
Probable cause: SPN missing. Register the full expected set on the account the service runs as. Nothing is written without -Confirm.
Invoke-SpnLifecycle -ProviderId <provider> -WhatIf Invoke-SpnLifecycle -ProviderId <provider> -Confirm
duplicate
Probable cause: duplicate SPN. The KDC returns KRB_ERR_S_PRINCIPAL_UNKNOWN because it cannot choose a key. Remove from the account the service does not run as.
Invoke-SpnDuplicateScan $plan | Invoke-SpnExecutionEngine -Mode Remove -Confirm
which
Is that account the one the service actually runs as?
Yes → enc · No — it is on the machine account → wrong · Not sure → wrong
wrong
Probable cause: SPN on the wrong account. The ticket is encrypted with a key the service does not hold. Move it to the service account. For an FCI, that is the service account for the cluster network name.
Invoke-SpnLifecycle -ProviderId <provider> -WhatIf
enc
Has the domain moved to AES-only, or was KB5021131 applied recently?
Yes or not sure → etype · No → keytab
etype
Probable cause: encryption-type mismatch (KDC_ERR_ETYPE_NOSUPP). The account is RC4-only or its attribute is unset. Set AES, then reset the password so AES keys exist.
Get-EncryptionTypeAudit
keytab
Does the service authenticate from a keytab (Linux, Java, Oracle, SAP, appliance)?
Yes → kvno · No → verify
kvno
Probable cause: stale keytab. A password reset incremented the KVNO; the keytab still holds the old key (KRB_AP_ERR_MODIFIED). Regenerate the keytab on the host. SpnManager will write the runbook; it will not touch the keytab.
Get-KeytabDriftAudit | Export-KeytabDriftRunbook
some
Do the failing users share something: a subnet, a client OS, a group?
They are blocked from NTLM (Protected Users, NTLM policy) → missing · They connect by a different name (alias, short name) → alias · No pattern → dup
alias
Probable cause: the name they use has no SPN. Every name clients actually use, including CNAME aliases and NetBIOS short names, needs its own SPN on the same account.
Invoke-SpnLifecycle -ProviderId <provider> -WhatIf
hop
Which hop fails?
First hop is NTLM (check auth_scheme on the middle tier) → name · First hop is Kerberos; second fails → deleg
deleg
Probable cause: delegation. The middle tier account needs constrained delegation to the back-end SPN, and that SPN must actually be registered. The KCD audit cross-checks both.
Get-KcdDelegationAudit Get-RbcdDelegationAudit
verify
Read the negotiated mechanism from the service. For SQL Server, sys.dm_exec_connections.auth_scheme. For HTTP, the WWW-Authenticate exchange. The proof stage does this before and after a change.
SELECT auth_scheme FROM sys.dm_exec_connections WHERE session_id = @@SPID;