AADSTS50034 (UserAccountNotFound): Account Not in the Directory
Published · Updated
Entra ID could not find the account the sign-in asked for, so no password was ever checked; a run of these from one source is username enumeration against your tenant.
Did the attacker have the password? No — the password (or username) was wrong.
Microsoft's definition
UserAccountNotFound
UserAccountNotFound - To sign into this application, the account must be added to the directory. This error can occur because the user mis-typed their username, or isn't in the tenant. An application might have chosen the wrong tenant to sign into, and the currently logged in user was prevented from doing so since they did not exist in your tenant. If this user should be able to log in, add them as a guest. See docs here: Add B2B users.
Source: Microsoft Entra authentication and authorization error codes · checked against the published table on every build · look up another code
Where it appears
- Microsoft Sentinel / Log Analytics: the ResultType column of SigninLogs and AADNonInteractiveUserSignInLogs
- Microsoft Graph signIns API and JSON exports: status.errorCode, with the text in status.failureReason
- Entra admin center sign-in log download (CSV): the Sign-in error code column
- 1 Stops here
Account
Exists, is enabled, is not locked out or blocked
- 2
Password
The password or other first factor is checked
- 3
Conditional Access
Policies, risk included, block or require more
- 4
MFA
The second factor is completed, or registered
- 5
Signed in
A token is issued; ResultType 0
Microsoft: “Conditional Access policies are enforced after first-factor authentication is completed.” Conditional Access overview ↗︎
What it means
Before Entra ID can check anything else, it has to resolve the name in the request to an account in the tenant that is handling the sign-in. AADSTS50034 is recorded when that lookup fails. Microsoft’s causes are a mistyped username, a user who “isn’t in the tenant”, an application that “might have chosen the wrong tenant to sign into”, and external people who need to be added as B2B guests.
For triage, the useful consequence is that nothing was validated. No password was compared, no MFA requirement was evaluated, no Conditional Access decision was reached on a real identity. The entry records the string that was submitted — in Sentinel that is normally what you see in UserPrincipalName — plus the source address, application and client.
That same clarity is what makes the code interesting to an attacker. A name that does not exist produces 50034; a name that does exist and fails credential validation produces AADSTS50126. Anyone collecting those responses is separating real accounts from invented ones before spending attempts on passwords.
Is it an attack?
| Pattern | Reading |
|---|---|
| One or two entries for a person, then a success under their correct UPN | A typo, an alias used instead of the UPN, or an old domain suffix after a rename |
| Regular entries from one application or script, always the same name | A deleted or renamed account still configured somewhere |
| One external user, one app, repeatedly | Guest who was never invited, or an app sending sign-ins to the wrong tenant |
| Many distinct names from one IP or ASN within minutes | Directory enumeration (T1087.004) using harvested or generated name patterns |
| 50034 for many names, then 50126 for a shorter list from the same source | The list has been filtered and password attempts have started |
Weight the source as much as the count: hosting, VPN or Tor addresses, a user agent that is clearly a tool, or a ClientAppUsed value for a legacy protocol all make user error an unlikely explanation. Enumeration also shows up in AADNonInteractiveUserSignInLogs, so query both tables.
How to investigate
Start by finding sources that tried many different names:
SigninLogs
| where TimeGenerated > ago(7d)
| where ResultType == "50034"
| summarize Attempts = count(), Names = dcount(UserPrincipalName),
NamesTried = make_set(UserPrincipalName, 20),
Apps = make_set(AppDisplayName, 5),
Clients = make_set(ClientAppUsed, 5)
by IPAddress, Location
| where Names >= 5
| order by Names desc
Then ask the question that sets the severity — did that source also touch accounts that do exist?
SigninLogs
| where TimeGenerated > ago(7d)
| where ResultType in ("50034", "50126", "0")
| summarize NotFound = countif(ResultType == "50034"),
CredentialFailures = countif(ResultType == "50126"),
Successes = countif(ResultType == "0"),
Users = dcount(UserPrincipalName),
LastSeen = max(TimeGenerated)
by IPAddress
| where NotFound > 0 and (CredentialFailures > 0 or Successes > 0)
| order by NotFound desc
An address with 50034 only has learned which names are wrong. An address that moved on to 50126, or that produced a success, has moved past enumeration: treat the accounts it reached as targets, check them for AADSTS50053 lockouts and for MFA-stage codes, and verify every successful sign-in it generated.
For the benign outcomes, fix the cause rather than the alert: correct the UPN the user is typing, point the application at the right tenant, or invite the external person as a guest. If the attempts are reaching legacy authentication endpoints, the legacy-auth MFA bypass rule covers the follow-on risk once the attacker has a name that works.
Related codes
- AADSTS50126 InvalidUserNameOrPassword Entra ID rejected the password (or the username) for this sign-in. One failure is a typo; the same failure across many accounts from one IP is password spraying.
- AADSTS50053 This error can result from two different reasons: IdsLocked Entra ID refused the sign-in before accepting it: either smart lockout has locked the account after repeated failures, or the source IP was blocked for malicious activity.
- AADSTS50020 UserUnauthorized
- AADSTS90072 PassThroughUserMfaError
- AADSTS50128 Invalid domain name
- AADSTS50059 MissingTenantRealmAndNoUserInformationProvided
Detect it
Frequently Asked Questions
- Does AADSTS50034 mean someone guessed a password?
- No. The sign-in stopped at the directory lookup, before any credential could be compared, because the name presented does not match an account in the tenant that handled the request. The code tells you a name was tried and that the name is not yours; it says nothing about whether the sender knows any real password.
- Why do real employees sometimes get AADSTS50034?
- The usual causes are the ones Microsoft lists: a mistyped username, or an account that simply is not in the tenant the application sent the request to. In practice that shows up as people typing a mail alias or an old domain suffix instead of their user principal name, as applications pinned to the wrong tenant, and as partners who have never been invited as B2B guests.
- How is AADSTS50034 different from AADSTS50126?
- 50034 means the account was not found at all; 50126 is the credential-validation failure for a sign-in where a username and password were checked. That difference is useful to you and to an attacker — a tool that sees 50034 for one name and 50126 for another has learned which names exist, which is why a burst of 50034 followed by 50126 against a smaller set of names is a spray being aimed.
- Should a burst of AADSTS50034 from one IP be alerted on?
- Yes, when one source produces the code for many distinct names in a short period, especially if the names follow a predictable pattern such as first.last@yourdomain. That is directory enumeration rather than user error. Record the source address and compare it against your other sign-in failures and successes before deciding whether the enumeration ever turned into an authentication attempt that worked.
Find AADSTS50034 in your own logs
Drop an Entra ID sign-in export into the free browser analyzer to see which users and IPs hit this code (nothing is uploaded), or run it through LogTriage for threat-intel enrichment and an AI-written incident report.