Event ID 4625 Windows Security log

Event ID 4625: An Account Failed to Log On — Reading Status and Sub Status

Published

Windows rejected a logon attempt — the Status and Sub Status fields say why it failed, and the logon type, workstation name and source address say where the attempt came from.

Logged on: The computer where the logon attempt was made — Microsoft states it generates on domain controllers, member servers, and workstations.

Microsoft's title

4625(F): An account failed to log on.

Source: Microsoft's event 4625 documentation · field names checked against it on every build

Fields that matter in an investigation

FieldXML / SentinelWhat it tells you
Account Name TargetUserName The account that was specified in the logon attempt — the name the attacker or the user actually tried.
Account Domain TargetDomainName Domain or computer name for the target account; for local accounts it holds the name of the computer the account belongs to.
Logon Type LogonType How the logon was attempted — 2 interactive, 3 network, 5 service, 10 RemoteInteractive (Terminal Services or Remote Desktop) — which tells you which service was under attack.
Status Status The reason why logon failed, as an NTSTATUS value; for credential failures it is the general result and the precise cause sits in Sub Status.
Sub Status SubStatus Additional information about the logon failure — the code that separates a non-existent account, a wrong password and a locked or restricted account.
Failure Reason FailureReason Textual explanation of the Status field value, rendered from a message string such as the account lockout text.
Workstation Name WorkstationName Machine name from which the logon attempt was performed — often the only identifier when the attempt arrives over NTLM.
Source Network Address IpAddress IP address of the machine from which the logon attempt was performed; ::1 or 127.0.0.1 means localhost, and IPv4 clients arrive as ::ffff:IPv4.
Authentication Package AuthenticationPackageName Which package handled the attempt — NTLM, Kerberos or Negotiate — which tells you whether a protocol that should not be in use was tried.
Caller Process Name ProcessName Full path and name of the executable of the process that attempted the logon; an unexpected path is one of Microsoft's own monitoring recommendations.

What it records

Event 4625 is Windows saying a logon attempt was rejected. Microsoft’s description is blunt: “This event is logged for any logon failure.” It belongs to the Audit Account Lockout and Audit Logon subcategories, and “It generates on the computer where logon attempt was made” — so a failed RDP session to a jump box is logged on the jump box, not on the domain controller. Microsoft adds that the event generates on domain controllers, member servers, and workstations.

The useful content is spread across four groups of fields. Account For Which Logon Failed holds the target: Security ID, Account Name and Account Domain. Failure Information holds Status (“the reason why logon failed”), Sub Status (“additional information about logon failure”) and Failure Reason, a textual explanation of the Status value. In practice credential failures carry the general result in Status and the specific cause in Sub Status, which is why 0xC000006D so often sits beside 0xC000006A or 0xC0000064.

Network Information gives Workstation Name (“machine name from which logon attempt was performed”) and Source Network Address, an IPv6 or ::ffff:IPv4 address, with ::1 or 127.0.0.1 meaning localhost and Source Port 0 for interactive logons. Detailed Authentication Information names the Logon Process, the Authentication Package (NTLM, Kerberos or Negotiate), Package Name (NTLM only) and Key Length, which is always 0 when Kerberos was used, including when Kerberos was negotiated through Negotiate.

Logon Type decides how you read everything else: 2 is interactive, 3 is network, 4 batch, 5 service, 7 unlock, 8 NetworkCleartext, 9 NewCredentials, 10 RemoteInteractive via Terminal Services or Remote Desktop, 11 CachedInteractive.

When it matters

A single 4625 is a typo. Volume and shape make it an incident:

PatternReading
Many failures for one account from one source in minutesBrute force; expect a lockout (0xC0000234) and event 4740
One source, a few failures each across many accountsPassword spraying — the basis of the 4625 spray rule
A run of names that do not exist (0xC0000064)Microsoft notes several of these in a row “can be a sign of a user enumeration attack”
Logon Type 10 from an external addressExposed Remote Desktop under attack
Repeated failures for a service accountMicrosoft recommends monitoring all 4625 events for service accounts, “because these accounts should not be locked out or prevented from functioning”

Microsoft also recommends monitoring all 4625 events for local accounts, “because these accounts typically should not be locked out”, watching for a mismatch between logon type and account (Logon Type 4 or 5 used by a domain administrator), and flagging a Caller Process Name outside a standard folder or containing restricted substrings.

How to investigate

Start by ranking sources on how many distinct accounts each one failed against — that separates spraying from a stale password:

SecurityEvent
| where TimeGenerated > ago(24h)
| where EventID == 4625
| summarize Failures = count(), Accounts = dcount(TargetUserName),
            AccountList = make_set(TargetUserName, 20),
            SubStatusCodes = make_set(SubStatus, 10),
            LogonTypes = make_set(LogonType, 5)
    by IpAddress, WorkstationName, Computer
| order by Accounts desc, Failures desc

Then pull the full field set for one account or one source to see protocol, process and timing:

SecurityEvent
| where TimeGenerated > ago(7d)
| where EventID == 4625 and TargetUserName =~ "svc_backup"
| project TimeGenerated, Computer, TargetUserName, TargetDomainName, LogonType,
          Status, SubStatus, IpAddress, WorkstationName, LogonProcessName,
          AuthenticationPackageName, ProcessName
| order by TimeGenerated asc

Regular failures every few minutes from an internal host, always the same process, point at a stored credential in a service or scheduled task. Irregular bursts from one address do not.

Finally, answer the question that sets severity — did the same source and account later succeed?

let failures = SecurityEvent
    | where TimeGenerated > ago(1d) and EventID == 4625
    | summarize FailCount = count(), LastFail = max(TimeGenerated) by IpAddress, TargetUserName;
SecurityEvent
| where TimeGenerated > ago(1d) and EventID == 4624
| join kind=inner failures on IpAddress, TargetUserName
| where TimeGenerated > LastFail
| project TimeGenerated, Computer, TargetUserName, IpAddress, LogonType, FailCount

A 4624 after a run of 4625s from the same source is a compromised account: reset it, check 4672 for privileges assigned to that session, and review 4648 for onward use of explicit credentials. Without a SIEM, export the Security log as XML from Event Viewer and load it into the free browser log analyzer, which groups 4625 events by source and Sub Status.

Related events and codes

  • Event ID 4624 An account was successfully logged on.
  • Event ID 4648 A logon was attempted using explicit credentials.
  • Event ID 4672 Special privileges assigned to new logon.
  • Event ID 4740 A user account was locked out.
  • Event ID 4768 A Kerberos authentication ticket (TGT) was requested.
  • Event ID 4771 Kerberos pre-authentication failed.
  • Event ID 4776 The computer attempted to validate the credentials for an account.
  • 0xC0000064 Someone tried to log on with an account name that does not exist. Occasional typos are normal; bursts of invented names from one source are username guessing or spraying with a generic list.
  • 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.
  • 0xC000006D The logon was rejected as invalid without saying which half was wrong — it is the general failure result that event 4625 usually carries in Status, with the real reason in Sub Status.
  • 0xC000006E The username and the authentication information were valid, but a restriction on the account — Microsoft's example is time-of-day restrictions — stopped the logon before it succeeded.
  • 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.
  • 0xC00002EE The authentication exchange was torn down before it finished, so Windows recorded the attempt as a logon failure — the code describes an abandoned handshake, not a rejected username or password.

Detect it

MITRE ATT&CK: T1110T1110.001T1110.003T1078

Frequently Asked Questions

Does a 4625 tell me whether the password was correct?
Not on its own — you have to read Sub Status. 0xC0000064 means the account name did not exist, 0xC000006A means the account exists and the password was wrong, and codes such as 0xC0000234 (locked out) describe the state of the account rather than the credential that was supplied.
Which Sub Status values should I prioritise?
Microsoft's monitoring table for this event calls out 0xC0000064, 0xC000006A, 0xC000006D, 0xC000006F (logon outside authorized hours), 0xC0000070 (unauthorized workstation), 0xC0000072 (account disabled by administrator) and 0xC0000193 (expired account), and says to watch especially for several of these events in a row for critical or service accounts.
The Source Network Address is 127.0.0.1 or ::1 — where did the attempt come from?
Microsoft documents those values as localhost, so the attempt was made on the machine that logged the event rather than across the network. Use Workstation Name, Logon Type and Caller Process Name instead to work out which local process or signed-in session generated the failure.
Why do I see 4771 on the domain controller but 4625 on the server?
4625 is written by the computer where the logon attempt was made, so a failed logon to a member server appears there, while the domain controller records Kerberos pre-authentication failures as 4771 and NTLM credential validation as 4776. Correlating all three gives you both the target host and the account the DC was asked about.

Find every 4625 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.