AADSTS50097: Device authentication required
Short answer: AADSTS50097 means Microsoft Entra ID asked the client to prove the device's identity because a device-based Conditional Access policy applies. Managed clients answer it silently. Clients that can't prove a device identity stop here. A spike for one user from a new IP can mean a valid credential is being used on an unmanaged device.
| Code | AADSTS50097 |
|---|---|
| Microsoft name | DeviceAuthenticationRequired |
| Category | Devices |
| Type | Interrupt (an expected extra step, not a failure) |
| Attack signal | Medium: worth a look in context |
| MITRE ATT&CK | T1078.004 Valid Accounts: Cloud Accounts |
| Where to look | SigninLogs, AADNonInteractiveUserSignInLogs |
| Microsoft lookup | login.microsoftonline.com/error?code=50097 |
What does AADSTS50097 mean?
Section titled “What does AADSTS50097 mean?”DeviceAuthenticationRequired: Device authentication is required.
The MSAL.NET documentation explains when it happens:
This error happens when a conditional access policy is applied to the resource you are accessing, which required that the device from which the token is acquired be managed by the organization, and that MSAL.NET proves this identity.
So 50097 is a request for proof, not a final verdict. A client on a managed device that can present the device identity continues. A client that can’t present it stops here.
Is it an attack?
Section titled “Is it an attack?”Mostly not. 50097 is often a step inside a normal sign-in on a managed device, or a client app (custom MSAL code, a script, a non-broker client) that doesn’t support device authentication.
The security reading: a device-based policy is asking the caller to prove it is one of your devices. An attacker’s machine can’t.
| Pattern | Likely meaning |
|---|---|
| 50097 followed by a success for the same user, device and app within seconds | Normal device-authentication step. Benign. |
| Repeated 50097 from one internal app or script | The client doesn’t support device authentication. Developer or configuration issue. |
| 50097 for one user from a new IP, no device ID, no success afterwards | A valid credential on an unmanaged device. Investigate. |
| 50097 alongside 53000 or 53001 for the same user and IP | Same story from a different angle: device policy is stopping a working credential. |
These readings are based on what Microsoft says the code means. Microsoft doesn’t publish a threat pattern for 50097 specifically.
How do I find it in my logs (KQL)?
Section titled “How do I find it in my logs (KQL)?”50097 that never turned into a success for the same user and IP within ten minutes:
let window = 10m;let challenges = SigninLogs | where TimeGenerated > ago(7d) | where ResultType == "50097" | project ChallengeTime = TimeGenerated, UserPrincipalName, IPAddress, AppDisplayName, DeviceId = tostring(DeviceDetail.deviceId), OS = tostring(DeviceDetail.operatingSystem), ClientAppUsed, UserAgent;let successes = SigninLogs | where TimeGenerated > ago(7d) | where ResultType == "0" | project SuccessTime = TimeGenerated, UserPrincipalName, IPAddress;challenges| join kind=leftouter successes on UserPrincipalName, IPAddress| extend Followed = SuccessTime between (ChallengeTime .. (ChallengeTime + window))| summarize Completed = countif(Followed) by ChallengeTime, UserPrincipalName, IPAddress, AppDisplayName, DeviceId, OS, ClientAppUsed, UserAgent| where Completed == 0| sort by ChallengeTime descVolume per user and IP, to spot a new source:
SigninLogs| where TimeGenerated > ago(7d)| where ResultType == "50097"| summarize Attempts = count(), Apps = make_set(AppDisplayName, 5), DeviceIds = make_set(tostring(DeviceDetail.deviceId), 5), FirstSeen = min(TimeGenerated) by UserPrincipalName, IPAddress| sort by Attempts descOn AADNonInteractiveUserSignInLogs, DeviceDetail is a string column: use parse_json(DeviceDetail).deviceId. The DeviceDetail property names follow the Microsoft Graph signIn device detail object; check them against one row in your own workspace first.
How does Conditional Access affect it?
Section titled “How does Conditional Access affect it?”- 50097 comes from a Conditional Access policy that depends on the device (for example a compliant or hybrid joined device requirement). The Conditional Access tab on the sign-in shows which policy applied.
- If the client can’t prove the device and the policy still isn’t satisfied, expect the final row to be a device failure such as 53000 or 53001, or a block.
- This is a strong control against stolen passwords and phished sessions, because the proof is tied to a device you manage.
How do I fix AADSTS50097?
Section titled “How do I fix AADSTS50097?”For the user: sign in from a managed corporate device, using an app or browser your IT team supports for device sign-in.
For developers: follow Microsoft’s MSAL.NET page on device authentication errors (linked in sources) so the client can prove the device identity, or ask the admin whether the app should be in scope of a device-based policy.
For admins:
- Check whether the 50097 was followed by a success (first query). If yes, it was a normal step.
- If not, and the IP or device is new for that user, treat the credential as exposed: reset the password, revoke sessions, review other sign-ins from that IP.
- For an internal app that keeps failing, fix the client before you exclude it from the policy.