Skip to content

How to Audit Failed Logons in Active Directory

Audit failed logons in Active Directory: enable the right audit policy, read Event ID 4625, decode logon types and failure codes, and trace where bad attempts come from.

MGMCSA Guru Team November 10, 2026 8 min read
Photographic illustration for How to Audit Failed Logons in Active Directory: enterprise server room with directory and network admin console

Failed logons are one of the most useful signals in Active Directory. A handful of them is usually someone fat-fingering a password. A flood of them across dozens of accounts from one source is a password spray in progress. The difference is right there in the Security event log — if you’ve turned on the right auditing and you know how to read Event ID 4625.

This guide gets you from “I’m not sure if we even log this” to “I can tell who failed to log on, from where, and why.” We’ll enable the correct audit policy, break down the fields in a 4625 event (especially the failure codes everyone ignores), and pull the events with PowerShell so you’re not clicking through Event Viewer one entry at a time.

The key event is 4625, “An account failed to log on.” Everything here revolves around capturing it and interpreting it.

First, turn on logon auditing

You can’t audit what you never enabled. Failed logon auditing is controlled by the Advanced Audit Policy, configured through Group Policy and applied to your domain controllers and member servers.

The path in a GPO:

Computer Configuration
  > Policies
    > Windows Settings
      > Security Settings
        > Advanced Audit Policy Configuration
          > Audit Policies
            > Logon/Logoff
              > Audit Logon  ->  Success and Failure

For tracking failed logons you need Failure at minimum; enabling Success too gives you the full picture (and lets you confirm a legitimate logon eventually succeeded after some failures).

Verify what’s actually applied on a given server:

# Check the effective setting for the Logon subcategory
auditpol /get /subcategory:"Logon"

You want it reporting Success and Failure (or at least Failure) for the Logon subcategory. Apply the GPO to the Domain Controllers OU so all DCs audit consistently, and to member servers via their own policy.

Where failed logons get logged

This trips people up: the 4625 event lands on the machine that processed the authentication, which isn’t always where you’d expect.

Where to look for 4625

Domain account, network logon Often the domain controller that handled the authentication
Interactive logon at a workstation The workstation's local Security log
RDP to a server The target server's Security log (logon type 10)
Service or scheduled task The server running the service

Because a domain has multiple DCs and many servers, the only way to get a complete picture is to collect Security logs centrally — via Windows Event Forwarding or a SIEM — so you can search across all of them at once. Hunting on individual machines works for a single incident but doesn’t scale.

Reading an Event ID 4625

A 4625 event has more in it than most people read. Here are the fields that matter:

Key fields in Event 4625

Account For Which Logon Failed The target username and domain — who someone tried to log in as
Logon Type How the logon was attempted (see table below)
Workstation Name The source machine name, when available
Source Network Address The source IP — the most useful field for tracing attacks
Failure Reason / Status / Sub Status Why it failed, as text and as hex codes
Caller Process Name The process that requested the logon, on local failures

Logon types

The Logon Type tells you the nature of the attempt, which matters a lot for triage:

Common logon types

2 Interactive — someone at the console / keyboard
3 Network — accessing a share or service over the network
4 Batch — scheduled task
5 Service — a service starting under an account
7 Unlock — unlocking a locked session
8 NetworkCleartext — credentials sent in cleartext (e.g. some basic auth)
10 RemoteInteractive — RDP / Terminal Services

A burst of type 3 failures from one IP across many usernames is a network-based spray. A type 10 failure spike is someone hammering RDP. Knowing the type points you at the right exposure.

Failure codes — the part everyone skips

The Status and Sub Status hex codes are where the real story is. The on-screen “Failure Reason” text is vague; the sub-status code is precise.

Common 4625 status / sub-status codes

0xC000006A Wrong password (the username exists)
0xC0000064 Username does not exist
0xC0000234 Account is currently locked out
0xC0000072 Account is disabled
0xC0000071 Password has expired
0xC0000070 Logon not allowed from this workstation (workstation restriction)
0xC000006F Logon outside of allowed hours / time restriction
0xC0000193 Account has expired

This distinction drives your response. Many 0xC0000064 failures (nonexistent usernames) from one source is classic spraying — the attacker is guessing account names. Repeated 0xC000006A (bad password) against valid accounts is brute force against known users. A single 0xC0000234 is just someone who already locked themselves out.

Pulling 4625 events with PowerShell

Event Viewer is fine for one event. For analysis, use Get-WinEvent.

# Get the last 50 failed logons on this server
Get-WinEvent -FilterHashtable @{ LogName = 'Security'; Id = 4625 } -MaxEvents 50 |
  Select-Object TimeCreated, Message

Filter to a time window — for example failed logons in the last 24 hours:

$start = (Get-Date).AddDays(-1)
Get-WinEvent -FilterHashtable @{ LogName='Security'; Id=4625; StartTime=$start } |
  Select-Object TimeCreated, Message

Group failures by source IP to spot an attacker quickly:

# Count failed logons per source IP in the last day
$start = (Get-Date).AddDays(-1)
Get-WinEvent -FilterHashtable @{ LogName='Security'; Id=4625; StartTime=$start } |
  ForEach-Object { ([xml]$_.ToXml()).Event.EventData.Data |
    Where-Object { $_.Name -eq 'IpAddress' } | Select-Object -ExpandProperty '#text' } |
  Group-Object | Sort-Object Count -Descending |
  Select-Object Count, Name

That last one is the workhorse for an active incident — it turns thousands of raw events into a short list of source IPs ranked by how many failures each generated.

Triage: attack or accident?

When you see failed logons, ask three questions in order:

  1. How many, and how fast? A few over an afternoon is noise. Hundreds in minutes is an event.
  2. One account or many? One account failing repeatedly is often a stuck saved credential or a forgotten password. Many different accounts from one source is spraying.
  3. Where from? An internal admin subnet is likely benign. An unexpected public IP, or a server that has no business authenticating users, is a red flag.

Keep the evidence

Audit data only helps if it survives long enough to use.

Failed logon auditing checklist

  • Advanced Audit Policy > Logon/Logoff > Audit Logon set to Failure (and Success)
  • Advanced audit policy forced to override the legacy basic categories
  • Policy applied to the Domain Controllers OU and to member servers
  • Security log size increased so events aren't overwritten too fast
  • Security logs forwarded to a central collector / SIEM
  • A documented way to group 4625 by source IP and status code

For a broader view of which audit categories belong on a domain controller, the auditing section of the Windows Server hardening checklist lines up the full set worth enabling.

Wrapping up

Auditing failed logons in Active Directory is two skills: turning on the right policy so 4625 events are actually captured, and reading those events properly once you have them. The fields that matter most are the logon type, the source network address, and the sub-status code — together they tell you whether you’re looking at a typo, a stale saved credential, or a spray hitting your domain.

Set the advanced audit policy on your DCs and servers, forward the logs somewhere central, and keep the status-code table handy. When something does go wrong, you’ll be reading a clear story instead of guessing.

Frequently asked questions

What event ID is a failed logon in Windows?

Event ID 4625, 'An account failed to log on', logged in the Security event log. It records the account that was targeted, the logon type, the source workstation and IP where possible, and a status/sub-status code explaining why the logon failed. It's the primary event for tracking failed sign-in attempts.

Where do failed logon events appear — the DC or the workstation?

It depends on where the logon was attempted. Domain account authentication failures often show on the domain controller that handled the request, while interactive failures at a workstation are logged on that machine. For a domain-wide view you collect Security logs from all DCs and relevant servers into one place.

How do I enable failed logon auditing?

Use the advanced audit policy via Group Policy: under Security Settings > Advanced Audit Policy Configuration > Logon/Logoff, set 'Audit Logon' to capture Failure (and usually Success too). Apply it to domain controllers and member servers. The advanced audit policy is preferred over the older basic audit categories and shouldn't be mixed with them.

What does the status code in Event 4625 mean?

The Status and Sub Status fields are codes that explain the failure reason. For example 0xC000006A means a bad password, 0xC0000064 means the user name doesn't exist, and 0xC0000234 means the account is locked out. Reading the sub-status is how you tell a typo apart from a password-spray attempt.

How can I tell if failed logons are an attack or just user error?

Look at volume, spread, and source. A few 4625 events for one user with a bad-password code is usually a forgotten password. Many failures across many different usernames from one source IP, or the same account failing from an unexpected external address, points to spraying or brute force. Correlate by source IP and time.

Does auditing failed logons slow down the server?

Logon auditing has minimal performance impact, but on busy domain controllers it generates a lot of events, which can fill the Security log quickly. Set an adequate log size, and forward events to a central collector or SIEM so older events aren't overwritten before you can review them.

Sources & further reading

Official vendor documentation referenced while writing this guide.

MG

MCSA Guru Team

IT & Systems Administration

We are working IT pros and system administrators who spend our days in Windows Server, Microsoft 365, and the wider Microsoft stack. MCSA Guru is where we write down the fixes and walkthroughs we wish we had found the first time.

MCSA Guru provides independent, educational IT guidance. Microsoft, Windows, Windows Server, Microsoft 365, Exchange, and Microsoft Teams are trademarks of Microsoft Corporation; Docker is a trademark of Docker, Inc. MCSA Guru is not affiliated with or endorsed by Microsoft or Docker. Always test changes in a safe environment before applying them in production.

Related guides

Fixing something right now?

Jump straight into the guide library or search for the exact error or task you are dealing with.