Event ID 4771: Kerberos Pre-Auth Failed — What the Failure Code Means
Published
A domain controller refused to issue a Kerberos TGT — the Failure Code says whether the password was wrong, the password expired, the account's credentials revoked, or a smart card certificate was missing.
Logged on: A domain controller — Microsoft states the event generates only on domain controllers, and lists Active Directory domain controller as the required server role.
Microsoft's title
4771(F): Kerberos pre-authentication failed.
Source: Microsoft's event 4771 documentation · field names checked against it on every build
Fields that matter in an investigation
| Field | XML / Sentinel | What it tells you |
|---|---|---|
| Security ID | TargetSid | SID of the account object for which the TGT was requested; Microsoft's monitoring guidance for this event is built around watching this value for high-value, non-active and allow-listed accounts. |
| Service Name | ServiceName | The name of the service in the Kerberos realm the TGT request was sent to — typically krbtgt/DOMAIN_NETBIOS_NAME or krbtgt/DOMAIN_FULL_NAME, confirming this was a ticket-granting-ticket request. |
| Client Address | IpAddress | IP address of the computer the TGT request came from; formats include IPv4, IPv6, ::ffff:IPv4_address and ::1 for localhost, so this is the field you pivot on to find the source host. |
| Client Port | IpPort | Source port of the client connection that carried the TGT request; 0 for local (localhost) requests. |
| Failure Code | Status | Hexadecimal failure code of the failed TGT issue operation — the single field that separates a wrong password (0x18) from an expired password (0x17), revoked credentials (0x12) or a smart card certificate problem (0x10). |
| Authentication Type | PreAuthType | The code of the pre-authentication type used in the TGT request — 2 (PA-ENC-TIMESTAMP) is normal for standard password authentication, 15, 16 and 17 appear in smart card scenarios, and 138 is logon using Kerberos Armoring (FAST). |
| Certificate Issuer Name | CertIssuerName | Name of the certification authority that issued the smart card certificate — Microsoft documents it as always empty for 4771 events, so do not expect smart card detail here. |
| Certificate Thumbprint | CertThumbprint | Thumbprint of the smart card certificate; like the other certificate fields, always empty for 4771 events. |
What it records
Event 4771 belongs to the Audit Kerberos Authentication Service subcategory, and Microsoft’s description of it is short: “This event generates every time the Key Distribution Center fails to issue a Kerberos Ticket Granting Ticket (TGT). This problem can occur when a domain controller doesn’t have a certificate installed for smart card authentication (for example, with a “Domain Controller” or “Domain Controller Authentication” template), the user’s password has expired, or the wrong password was provided.”
Two scoping rules matter for collection. “This event generates only on domain controllers” — so the host in Computer is the DC that handled the request, not the machine the user was sitting at; that machine appears in Client Address. And the event “is not generated if “Do not require Kerberos preauthentication” option is set for the account”, so accounts with pre-authentication disabled are invisible here.
Everything else in the event supports one question: why did the KDC refuse? Security ID and the account name identify who was being authenticated (computer accounts end with $), Service Name confirms the request went to krbtgt, Client Address and Client Port give the source, Authentication Type records which pre-authentication type was used, and Failure Code carries the hexadecimal reason, taken from the error codes defined in RFC 4120.
When it matters
Read the Failure Code first. These are the ones you will meet most often, with Microsoft’s descriptions:
| Code | Code name | Microsoft’s description |
|---|---|---|
| 0x6 | KDC_ERR_C_PRINCIPAL_UNKNOWN | Client not found in Kerberos database |
| 0x10 | KDC_ERR_PADATA_TYPE_NOSUPP | KDC has no support for PADATA type (pre-authentication data) |
| 0x12 | KDC_ERR_CLIENT_REVOKED | Clients credentials have been revoked |
| 0x17 | KDC_ERR_KEY_EXPIRED | Password has expired—change password to reset |
| 0x18 | KDC_ERR_PREAUTH_FAILED | Pre-authentication information was invalid |
| 0x25 | KRB_AP_ERR_SKEW | Clock skew too great |
For 0x18 Microsoft gives the possible cause as “The wrong password was provided”, which makes it the Kerberos equivalent of the matching status in 4625 and 4776 — 0xC000006A. A run of 0x18 for one account from one Client Address is the brute-force shape; one Client Address producing 0x18 across many different accounts is the spraying shape, and a lockout (0xC0000234, event 4740) often follows. 0x17 and 0x12 describe the state of the account rather than a guess, and usually explain a user who cannot work rather than an attacker. For 0x10, Microsoft’s documented causes are smart card logon where “the proper certificate cannot be located”, the wrong CA being queried or unreachable, or a domain controller without a Domain Controller / Domain Controller Authentication certificate.
Microsoft’s monitoring recommendations key all of this on Security ID: watch it for high-value accounts such as domain administrators, service accounts and domain controller accounts; watch it for non-active, disabled or guest accounts “that should never be used”; watch it against an allow list; and use it with other fields to spot anomalies such as “use of an account outside of working hours”.
How to investigate
Start by ranking sources — how many distinct accounts did each client fail against?
SecurityEvent
| where TimeGenerated > ago(24h)
| where EventID == 4771
| extend ClientIp = replace_string(IpAddress, "::ffff:", "")
| summarize Failures = count(), Accounts = dcount(TargetUserName),
AccountList = make_set(TargetUserName, 20), Codes = make_set(Status, 5),
FirstSeen = min(TimeGenerated), LastSeen = max(TimeGenerated)
by ClientIp, Computer
| order by Accounts desc, Failures desc
Then isolate the wrong-password code and look at it per account, which is the brute-force view:
SecurityEvent
| where TimeGenerated > ago(24h)
| where EventID == 4771 and Status =~ "0x18"
| extend ClientIp = replace_string(IpAddress, "::ffff:", "")
| summarize Failures = count(), Sources = dcount(ClientIp), SourceList = make_set(ClientIp, 10),
LastSeen = max(TimeGenerated)
by TargetUserName, TargetSid
| where Failures > 5
| order by Failures desc
The question that changes severity is whether any of those pairs then succeeded, so join the failures to successful logons from the same source:
let preauth = SecurityEvent
| where TimeGenerated > ago(24h) and EventID == 4771 and Status =~ "0x18"
| extend ClientIp = replace_string(IpAddress, "::ffff:", "")
| summarize FailCount = count(), LastFail = max(TimeGenerated) by TargetUserName, ClientIp;
SecurityEvent
| where TimeGenerated > ago(24h) and EventID == 4624
| join kind=inner preauth on TargetUserName, $left.IpAddress == $right.ClientIp
| where TimeGenerated > LastFail
| project TimeGenerated, Computer, TargetUserName, IpAddress, LogonType, FailCount, LastFail
| order by TimeGenerated asc
From there, pivot on the account and the client host: 4768 and 4769 for the rest of its Kerberos activity on the DC, 4776 for NTLM validation attempts for the same name, 4740 for a lockout, and 4723 or 4724 for a password change or reset that would explain a sudden wave of 0x18 from a service or scheduled task holding an old password. Ticket Options and the pre-authentication type live inside the event XML rather than in the SecurityEvent columns, so collect the raw event when you need them. If the failures group by source across many accounts, the Windows 4625 password-spray rule covers the same grouping on the member-server side. Without a SIEM, export the DC Security log as XML from Event Viewer and load it into the free browser log analyzer.
Related events and codes
- Event ID 4768 A Kerberos authentication ticket (TGT) was requested.
- Event ID 4769 A Kerberos service ticket was requested.
- Event ID 4776 The computer attempted to validate the credentials for an account.
- Event ID 4625 An account failed to log on.
- Event ID 4624 An account was successfully logged on.
- Event ID 4740 A user account was locked out.
- Event ID 4723 An attempt was made to change an account's password.
- Event ID 4724 An attempt was made to reset an account's password.
- 0x18 The domain controller rejected the pre-authentication data sent with a ticket request — Microsoft's listed cause is that the wrong password was provided; repeated 0x18 events for one account are a brute-force indicator.
- 0x17 The domain controller refused the ticket request because the account's password has expired and has to be changed before Kerberos will issue a ticket — routine for people, but a problem worth chasing when it hits service accounts or comes from an address you do not recognise.
- 0x12 The domain controller refused the ticket request because the account itself is barred from logging on — Microsoft's examples are an account that is disabled, expired or locked out — rather than because of anything about the password.
- 0x6 The domain controller could not find the requested account in its database — the name does not exist, and a run of these from one source is account enumeration.
- 0xC000006A The account exists and the password was wrong. One event is a typo; many against one account is brute force; one source failing across many real accounts is password spraying.
- 0xC0000234 The account is locked because the lockout threshold was reached; every further attempt fails with this code until the lockout ends or an administrator unlocks it.
Detect it
Frequently Asked Questions
- Does a 4771 always mean someone typed the wrong password?
- Only when the Failure Code is 0x18 (KDC_ERR_PREAUTH_FAILED), for which Microsoft lists the possible cause "The wrong password was provided." 0x17 is an expired password, 0x12 is revoked client credentials and 0x10 points at a smart card certificate problem, so read the code before calling it guessing.
- Why do some accounts never produce 4771 even when their authentication fails?
- Microsoft states this event "is not generated if "Do not require Kerberos preauthentication" option is set for the account." Those accounts skip pre-authentication altogether, and they are also the ones exposed to AS-REP roasting, so audit which accounts carry the flag instead of assuming 4771 covers everyone.
- Why does Client Address look like "::ffff:10.0.0.12"?
- Client Address is the IP address of the computer from which the TGT request was received, and Microsoft documents the formats as IPv6 or IPv4 address, ::ffff:IPv4_address, and ::1 for localhost. Strip the ::ffff: prefix before comparing the value with your IPv4 asset inventory.
- Are the certificate fields ever useful on a 4771?
- No. Microsoft notes that Certificate Issuer Name, Certificate Serial Number and Certificate Thumbprint are "Always empty for 4771 events". For a smart card failure (Failure Code 0x10) you have to check the domain controller's own certificates and the CA it queries, not this event.
Find every 4771 in your own logs
Load a Windows Security event export into the free browser analyzer to group events by account, source address and status, with password spraying, brute force and lockout storms flagged. Nothing is uploaded.