Log Dejargonizer

Windows Security Log · Event 4771

Event 4771: Kerberos pre-authentication failed

A domain controller refused a Kerberos sign-in, almost always because the password was wrong. In an Active Directory domain this is where failed sign-ins actually land, so it is usually more useful than hunting for 4625 on individual machines.

Also written as 4771Event ID 4771Kerberos pre-authentication failed

What it means for you

For an analyst

The Client Address field is genuine network data rather than a client-supplied name, which makes 4771 more trustworthy than 4776 for source attribution. Note it is often recorded in IPv6-mapped form. Failure code 0x18 is the one that means a wrong password.

What it looks like

Sanitised. Addresses come from the RFC 5737 documentation ranges.

Sample
Kerberos pre-authentication failed.

Account Information:
  Security ID:  CORP\jbrooks
  Account Name: jbrooks

Service Information:
  Service Name: krbtgt/CORP

Network Information:
  Client Address: ::ffff:192.0.2.44
  Client Port:    50912

Additional Information:
  Ticket Options: 0x40810010
  Failure Code:   0x18
  Pre-Authentication Type: 2

The fields that decide it

Everything else in the log line is context.

TargetUserName
The account that failed to authenticate.
ServiceName
The service the ticket was requested for. krbtgt means an initial sign-in rather than access to a specific service.
IpAddress
Where the request came from. Frequently written in IPv6-mapped form such as ::ffff:192.0.2.44.
Status
Why Kerberos refused the request.
  • 0x18The password was wrong. This is the overwhelming majority of 4771 events.
  • 0x6The account does not exist. A run of these is username enumeration.
  • 0x12The account is disabled, locked out, or expired.
  • 0x17The password has expired.
  • 0x25The clock on the client is too far out of sync with the domain controller.
  • 0x10Cryptographic mismatch — usually an encryption type the domain no longer accepts.
PreAuthType
How pre-authentication was attempted. Type 2 is the ordinary encrypted timestamp; type 0 means none was sent, which is worth noting.

Ordinary reasons this happens

Most of the time it is one of these.

  • A mistyped password, producing a single 0x18.
  • A saved credential on a phone, printer, or mapped drive still offering an old password on a schedule.
  • A machine whose clock has drifted more than five minutes, producing 0x25.
  • An expired password that the user has not been prompted to change yet.
  • Service accounts with outdated stored passwords retrying on a fixed interval.

When it is not ordinary

Password spraying against the domain.

What gives it awayMany distinct TargetUserName values with 0x18 from a single IpAddress, spread out to stay under the lockout threshold.

ATT&CK T1110.003

Username enumeration.

What gives it awayA run of 0x6 failures. Kerberos distinguishes a bad password from a nonexistent account, which is exactly what makes this cheap for an attacker.

ATT&CK T1589.002

Brute force against one account.

What gives it awayOne account, high volume of 0x18, usually ending in a 4740 lockout.

ATT&CK T1110.001

AS-REP roasting reconnaissance.

What gives it awayRequests with PreAuthType 0 for accounts that have pre-authentication disabled. Pair with 4768 to see the full picture.

ATT&CK T1558.004

What to do next

  1. Read the failure code before anything else. 0x18 and 0x6 mean very different things about what the other side already knows.
  2. Count distinct TargetUserName values per IpAddress over the last day. More than a handful is spraying.
  3. Strip the IPv6-mapped prefix from the address before comparing it against your network ranges.
  4. For 0x25, check the clock on the client rather than the account — it is a time problem, not a credential one.
  5. Look for a 4624 from the same address shortly afterwards to see whether anything succeeded.

Queries to run

kql Spraying, counted as distinct accounts per source rather than raw failure volume.
SecurityEvent | where EventID == 4771 | extend Code = tostring(Status) | summarize attempts = count(), accounts = dcount(TargetUserName) by IpAddress, Code, bin(TimeGenerated, 1h) | where accounts > 5 | order by accounts desc
kql Username enumeration against accounts that do not exist.
SecurityEvent | where EventID == 4771 and Status == '0x6' | summarize count() by IpAddress, bin(TimeGenerated, 30m) | where count_ > 10
splunk
index=wineventlog EventCode=4771 | stats count dc(user) as accounts by src_ip Failure_Code | where accounts > 5

Common questions

What does failure code 0x18 mean in Event 4771?

The password was wrong. It is by far the most common 4771 result and covers everything from a typo to a saved credential gone stale to deliberate password guessing — the difference is how many attempts there are and how many accounts they target.

Why do I see Event 4771 instead of 4625 in my domain?

Because Active Directory uses Kerberos by default, and Kerberos failures are recorded on the domain controller as 4771. 4625 is written on the machine the sign-in targeted, so if you only collect logs from domain controllers, 4771 is what you will see.

Why is the client address in Event 4771 written as ::ffff:192.0.2.44?

That is an IPv4 address expressed in IPv6-mapped notation. The address after the last colon is the real one. Strip the ::ffff: prefix before comparing it against your network ranges or your queries will silently match nothing.

What does failure code 0x25 mean?

The client's clock is more than five minutes out of step with the domain controller, and Kerberos refuses to authenticate across that gap by design. Fix time synchronisation on the client; the password is not the problem.

Read next

Mentioned by

Vendor documentation

Last reviewed 28 August 2026