AD Kerberos Encryption Troubleshooting
AD Kerberos Encryption Troubleshooting
A user can log on successfully but fail to obtain a ticket for one HTTP service. A single klist cache can also contain an AES TGT and an RC4 service ticket. Diagnose the exact SPN, service account, and TGS exchange.
The examples use Windows Server 2022 hosts LAB-DC1 and LAB-MEMBER in corp.test.checo.cc. HTTP/KB1RC4 demonstrates ticket failure after RC4 is disallowed; a separate account, kb4769-svc, shows how changing the service declaration affects the resulting ticket.
1. Bitmasks and type IDs
The account attribute is a bitmask; TicketEncryptionType is an algorithm identifier.
| Location | Value | Meaning |
|---|---|---|
| msDS-SupportedEncryptionTypes | 0x1 | DES-CBC-CRC bit, not RC4 |
| Same attribute | 0x4 / decimal 4 | RC4 bit |
| Same attribute | 0x8, 0x10 | AES128, AES256 bits |
| Same attribute | 0x18 / decimal 24 | AES128 plus AES256 |
| Same attribute | 0x1C / decimal 28 | RC4 plus both AES types |
| TicketEncryptionType | 0x17 | RC4-HMAC ticket |
| TicketEncryptionType | 0x11, 0x12 | AES128, AES256 tickets |
Higher bits express additional capabilities; this is not an exhaustive attribute definition for every version. Missing, explicit zero, and explicit four are not interchangeable. DC updates and KDC configuration affect fallback behavior. See the attribute's role.
2. AES TGT and RC4 service ticket
kb4769-svc owned HTTP/kb4769svc.corp.test.checo.cc and already had AES and RC4 keys. The experiment first set its declaration to four. After purging the intended client session and requesting that SPN:
TGT: krbtgt/CORP.TEST.CHECO.CC
KerbTicket Encryption Type: AES-256-CTS-HMAC-SHA1-96
Service: HTTP/kb4769svc.corp.test.checo.cc
KerbTicket Encryption Type: RSADSI RC4-HMAC(NT)The DC recorded:
TargetUserName = [email protected]
ServiceName = kb4769-svc
ServiceSid = S-1-5-21-3628476133-752301219-3504167884-6426
IpAddress = ::ffff:10.77.77.20
Status = 0x0
TicketEncryptionType = 0x17
ServiceSupportedEncryptionTypes = 0x4 (RC4)
ServiceAvailableKeys = AES-SHA1, RC4
ClientAdvertizedEncryptionTypes = AES256-CTS-HMAC-SHA1-96, AES128-CTS-HMAC-SHA1-96, RC4-HMAC-NT
SessionKeyEncryptionType = 0x17The client advertised AES and the service had AES keys, yet this service ticket used RC4. Changing the account declaration from four to 24, then purging/re-requesting, produced an AES256 service ticket. Both TicketEncryptionType and SessionKeyEncryptionType became 0x12, with ServiceSupportedEncryptionTypes=0x18.
The declaration was the decisive variable in this controlled comparison. It does not mean the service account alone always determines selection. Client requests, service capabilities and actual keys, KDC/host policies, and update-dependent rules jointly constrain the result. Changing those conditions can change the outcome for the same attribute value.

3. RC4-disabled failure
kb1-rc4user owned HTTP/KB1RC4 with the attribute set to four. At 12:38:30 its request succeeded with TicketEncryptionType=0x17. The experiment then restricted the host's allowed-type policy to AES128/AES256, read SupportedEncryptionTypes=24, and refreshed policy.
A fresh request failed:
klist get HTTP/KB1RC4
Current LogonId is 0:0x3e7
GetTicket substatus: 0x80090342
klist failed with 0xc00002fd/-1073741059:
The encryption type requested is not supported by the KDC.The 12:39:02 failure event contained:
ServiceName = HTTP/KB1RC4
Status = 0xe
TicketEncryptionType = 0xffffffff
ServiceSupportedEncryptionTypes = -
ServiceAvailableKeys = -0xe denotes KDC_ERR_ETYPE_NOSUPP. Missing capability fields must remain missing evidence; they do not locate an exact internal function or prove that key lookup never occurred. 0xffffffff does not identify a successfully issued new algorithm.
A separate TGT request for the account still succeeded at 12:39:18 with type 0x12. AS and TGS exchanges protect different ticket components under different constraints; successful logon does not rule out service-ticket failure.
Restoring the prior policy and requesting a fresh ticket succeeded at 12:40:25, again with 0x17. This demonstrates the allowed-type conflict in that configuration, not a completed AES migration or a successful end-to-end HTTP transaction. It also does not establish that every currently patched environment still permits RC4 by default.
4. Collect ticket evidence
Capture the service SID, SPN ownership, stored attribute, and password timestamp, then request in the actual calling session. These are reviewed examples:
# Management host: capture identity and the stored AD attribute first.
$dc = 'LAB-DC1.corp.test.checo.cc'
Get-ADUser kb4769-svc -Server $dc -Properties `
servicePrincipalName,msDS-SupportedEncryptionTypes,pwdLastSet,msDS-KeyVersionNumber |
Select-Object SamAccountName,SID,servicePrincipalName,
msDS-SupportedEncryptionTypes,pwdLastSet,msDS-KeyVersionNumber
setspn.exe -Q HTTP/kb4769svc.corp.test.checo.cc
# Request in the intended client logon session and record its LogonId.
klist
klist get HTTP/kb4769svc.corp.test.checo.cc
klistSYSTEM, administrator, and ordinary-user sessions have different logon IDs. Do not purge one and test another. The historical requests shown here used machine identity, not an ordinary user's console access. Existing tickets are not rewritten when the directory attribute changes.
Parse named fields on the DC that handled the request, rather than matching an account substring anywhere in XML:
# Run on the DC handling the request; adjust the historical window.
$start = (Get-Date).AddMinutes(-15)
Get-WinEvent -FilterHashtable @{LogName='Security';Id=4769;StartTime=$start} |
ForEach-Object {
$xml = [xml]$_.ToXml()
$d = @{}
foreach ($item in $xml.Event.EventData.Data) {
$d[[string]$item.Name] = [string]$item.'#text'
}
if ($d.ServiceName -eq 'kb4769-svc' -or
$d.ServiceName -eq 'HTTP/kb4769svc.corp.test.checo.cc') {
[pscustomobject]@{
Time = $_.TimeCreated; DC = $_.MachineName
RecordId = $_.RecordId; Version = $xml.Event.System.Version
Requester = $d.TargetUserName; Service = $d.ServiceName
ServiceSid = $d.ServiceSid; Client = $d.IpAddress
Status = $d.Status; TicketType = $d.TicketEncryptionType
SessionKeyType = $d.SessionKeyEncryptionType
ServiceTypes = $d.ServiceSupportedEncryptionTypes
ServiceKeys = $d.ServiceAvailableKeys
ClientTypes = $d.ClientAdvertizedEncryptionTypes
}
}
} | Sort-Object Time | Format-ListSuccessful ServiceName commonly identifies the account owning the SPN, not the full requested SPN; failure formatting can differ. Correlate the precise SPN using the client's Server line, directory ownership queries, or network evidence. A 4768 TGT ServiceName is not a substitute.
Use ServiceSid across account renames. Parse IPv4-mapped IPv6 normally rather than matching ambiguous address suffixes. Preserve ticket type, session-key type, capability masks, and available keys separately.
Extended fields depend on event version and installed updates. Microsoft's documented new format applies to relevant January 2025 and later cumulative updates. A missing field in an older record does not prove a missing key. Logged capability values can also be processed rather than identical to the raw AD attribute. See 4769 fields and versions.
5. Migrate to AES
This reproduces the declaration change for a dedicated account that already has AES keys. Preserve whether the original attribute existed:
# Dedicated lab account only; preserve whether the attribute existed.
$dc = 'LAB-DC1.corp.test.checo.cc'
$u = Get-ADUser kb4769-svc -Server $dc -Properties msDS-SupportedEncryptionTypes
$before = $u.'msDS-SupportedEncryptionTypes'
$backup = Join-Path $env:TEMP ('kb4769-etype-' + (Get-Date -Format yyyyMMdd-HHmmss) + '.clixml')
[pscustomobject]@{Guid=$u.ObjectGUID;Value=$before} | Export-Clixml -LiteralPath $backup
Set-ADUser -Identity $u.ObjectGUID -Server $dc -Replace @{'msDS-SupportedEncryptionTypes'=24}
# In the disposable client logon session; affects its entire ticket cache.
klist purge
klist get HTTP/kb4769svc.corp.test.checo.cc
klistNo password reset was required in this control because its recorded ServiceAvailableKeys already included AES. For older accounts, declaring AES does not create AES keys. If rotation is required, update dependent service configurations, tasks, application credentials, or keytabs together and check key versions. Do not promise that every service can remain running without a reload/restart.
Before removing RC4 broadly, inventory actual requests and legacy dependencies, then verify both AES issuance and business transactions service by service. Matching ServiceSupportedEncryptionTypes exactly to four misses multi-bit values and defaulted configurations. Likewise, the first AES ticket on a particular day does not prove an account-attribute change that day; policy, clients, and key rotation can also change selection. See Microsoft's RC4 detection/remediation guidance.
Restore the experiment from its captured state:
# Restore the captured value, not a guessed default.
$saved = Import-Clixml -LiteralPath $backup
if ($null -eq $saved.Value) {
Set-ADUser -Identity $saved.Guid -Server $dc -Clear 'msDS-SupportedEncryptionTypes'
} else {
Set-ADUser -Identity $saved.Guid -Server $dc -Replace @{
'msDS-SupportedEncryptionTypes'=[int]$saved.Value
}
}Restore domain policy through the owning GPO's baseline as well. Removing a registry value is restoration only when it was originally absent and no GPO subsequently replaces it. Decimal 31 is not a generic rollback value: it includes DES. The experiment's SupportedEncryptionTypes lived under HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System\Kerberos\Parameters; it is not the KDC DefaultDomainSupportedEncTypes setting.
6. Business validation
A fresh request for the same SPN should no longer return an unsupported-type error; DC Status should be zero, with the actual service-ticket type meeting policy in both DC/client evidence. AES128 can be acceptable when permitted; 0x12 is not the only valid result.
Then verify that the service decrypts the ticket and completes the transaction. With successful 4769 but application failure, inspect SPN ownership, actual service identity, synchronized password/keytab material, time, and service authorization. KDC issuance is one stage of authentication.
TicketOptions describes request options; klist Ticket Flags describes returned flags. The historical values were 0x40810000 and 0x40a10000, and the difference alone is not tampering evidence. Hashes can assist correlation, but applications reuse tickets and collection/retention is incomplete. A count of 4769 events is not a count of HTTP requests.
