Skip to content

AADSTS53003: Access blocked by Conditional Access

Short answer: AADSTS53003 means a Conditional Access policy blocked the sign-in or its grant controls weren't met. The password was already accepted, because Conditional Access only runs after the first factor succeeds. From an unknown IP or country, read it as a valid password in someone else's hands, stopped by policy. The ConditionalAccessPolicies column names the policy.

At a glance
CodeAADSTS53003
Microsoft nameBlockedByConditionalAccess
CategoryConditional Access
TypeFailure
Attack signalMedium: worth a look in context
MITRE ATT&CKT1078.004 Valid Accounts: Cloud Accounts
Where to lookSigninLogs, AADNonInteractiveUserSignInLogs
Microsoft lookuplogin.microsoftonline.com/error?code=53003

BlockedByConditionalAccess: Access has been blocked by Conditional Access policies. The access policy does not allow token issuance. If this is unexpected, see the Conditional Access policy that applied to this request or contact your administrator.

The row has ConditionalAccessStatus = failure. Microsoft defines that as: “The sign-in satisfied the user and application condition of at least one Conditional Access policy and grant controls are either not satisfied or set to block access.”

The key fact is the order of evaluation. A Microsoft moderator puts it plainly: “Conditional access policies only apply after the first factor of authentication is successfully completed.” So a 53003 means the password (or other first factor) was correct. That’s why Microsoft’s password spray playbook lists “53003 - User blocked by Conditional Access” among the events to review.

Pattern Likely meaning
A user on a new phone, a personal laptop, or travelling The policy doing its job on a real user. Benign, possibly a support ticket.
A block right after a CA policy change, hitting many users A policy scoped too wide. Configuration, not attack.
Non-interactive rows for an app that worked yesterday A token refresh blocked by a new or changed policy.
53003 from an IP or country the user has never used, with no matching travel A valid password in someone else’s hands, stopped by policy (T1078.004). Treat the password as compromised.
53003 from an IP that also produced many 50126 across users The spray found a correct password. CA was the only thing that stopped it.
Repeated 53003 for one user from an attacker IP, with changing clients or user agents Someone with the password is trying to find a client or app your policies don’t cover.

Which policies are blocking, and for whom. ConditionalAccessPolicies is a dynamic array in SigninLogs. Expand it and keep the policies whose result is failure:

SigninLogs
| where TimeGenerated > ago(1d)
| where ResultType == "53003"
| mv-expand Policy = ConditionalAccessPolicies
| where tostring(Policy.result) == "failure"
| project TimeGenerated, UserPrincipalName, IPAddress, AppDisplayName, ClientAppUsed,
PolicyName = tostring(Policy.displayName)
| summarize Blocks = count(),
Users = dcount(UserPrincipalName),
IPs = dcount(IPAddress),
Apps = make_set(AppDisplayName, 10)
by PolicyName
| sort by Blocks desc

53003 from IPs that also sprayed. These users have a known-good password:

let sprayIPs =
SigninLogs
| where TimeGenerated > ago(1d)
| where ResultType == "50126"
| summarize FailedUsers = dcount(UserPrincipalName) by IPAddress
| where FailedUsers >= 10
| project IPAddress;
SigninLogs
| where TimeGenerated > ago(1d)
| where ResultType == "53003"
| where IPAddress in (sprayIPs)
| project TimeGenerated, UserPrincipalName, IPAddress, AppDisplayName, ClientAppUsed, UserAgent
| sort by TimeGenerated asc

For token refreshes, run the first query against AADNonInteractiveUserSignInLogs. There ConditionalAccessPolicies is a string, so expand parse_json(ConditionalAccessPolicies) instead:

AADNonInteractiveUserSignInLogs
| where TimeGenerated > ago(1d)
| where ResultType == "53003"
| mv-expand Policy = parse_json(ConditionalAccessPolicies)
| where tostring(Policy.result) == "failure"
| summarize Blocks = count(), Users = dcount(UserPrincipalName)
by PolicyName = tostring(Policy.displayName), AppDisplayName
| sort by Blocks desc

The displayName and result field names inside each policy entry follow the Microsoft Graph sign-in object. Run the query once without the where filter to see the values your workspace holds.

How do Conditional Access and MFA affect it?

Section titled “How do Conditional Access and MFA affect it?”
  • 53003 is Conditional Access. The policy either blocks outright or requires something the sign-in couldn’t provide.
  • Microsoft’s troubleshooting guide says the Conditional Access tab on the sign-in entry “shows the specific policy or policies that resulted in the sign-in interruption.” Start there for a single case.
  • A 53003 with an unexpected source does not mean you are safe. CA stopped this attempt. The attacker still has the password and can try other apps, clients and locations.

For the user: the block is deliberate. Try again from a company device, a supported app, or your usual location. If it still fails, give your admin the time of the attempt and the correlation ID from the error page.

For admins:

  1. Open the sign-in entry, go to the Conditional Access tab, and find the policy with result Failure. Check which condition matched and which grant control failed.
  2. If the block was wrong for a real user, fix the policy scope or help the user meet the control. Don’t add a broad exclusion to make one ticket go away.
  3. If the source is unfamiliar, treat the password as compromised: reset it, revoke sessions (Revoke-MgUserSignInSession), and look for other sign-ins from the same IP.
  4. Look for successful sign-ins from the same IP to apps or clients your policy doesn’t cover.

Guides that use this code

Sources

  1. Microsoft Entra authentication and authorization error codes
  2. Troubleshoot sign-in problems with Conditional Access
  3. Password spray investigation (Microsoft incident response playbook)
  4. Sign-in log activity details
  5. Clarify what 50053 really means (Microsoft Q&A, community thread)
  6. SigninLogs table reference (Azure Monitor)