AADSTS70043: Refresh token expired due to sign-in frequency checks
Short answer: AADSTS70043 means a refresh token was refused because a Conditional Access sign-in frequency policy says the user must authenticate again. It is the session control working as configured, so it is expected and has low attack value. Volume tracks how strict your policy is. Hunt it in AADNonInteractiveUserSignInLogs with ResultType == "70043".
| Code | AADSTS70043 |
|---|---|
| Microsoft name | BadTokenDueToSignInFrequency |
| Category | Tokens and sessions |
| Type | Failure |
| Attack signal | Low: usually configuration or user error |
| Where to look | AADNonInteractiveUserSignInLogs |
| Microsoft lookup | login.microsoftonline.com/error?code=70043 |
What does AADSTS70043 mean?
Section titled “What does AADSTS70043 mean?”BadTokenDueToSignInFrequency: The refresh token has expired or is invalid due to sign-in frequency checks by Conditional Access. The token was issued on {issueDate} and the maximum allowed lifetime for this request is {time}.
An app tried to use a refresh token silently. A Conditional Access policy with a sign-in frequency session control says the user’s last authentication is too old for this request. The app has to send the user to an interactive sign-in.
Is it an attack?
Section titled “Is it an attack?”No. 70043 is a control you configured doing its job. Expect it wherever you have a sign-in frequency policy, and expect more of it the shorter the interval.
| Pattern | Likely meaning |
|---|---|
70043 for a user, followed by an interactive success in SigninLogs from the same IP and device |
Normal re-authentication. Benign. |
| A jump in 70043 volume on a specific day | Someone created or tightened a sign-in frequency policy. Check your Conditional Access change history. |
| 70043 for a user from an IP or device they don’t use, with no interactive sign-in following | An old refresh token being presented from somewhere unexpected. This is reasoning, not a documented detection: the control stopped it, but the token existed somewhere it shouldn’t. Investigate as a possible stolen token. |
The message includes the token’s issue date and the maximum allowed lifetime, so it tells you how old the token was when it was refused.
How do I find it in my logs (KQL)?
Section titled “How do I find it in my logs (KQL)?”Which apps and policies generate the volume:
AADNonInteractiveUserSignInLogs| where TimeGenerated > ago(7d)| where ResultType == "70043"| summarize Rows = count(), Users = dcount(UserPrincipalName), IPs = dcount(IPAddress) by AppDisplayName, ResourceDisplayName| sort by Rows descThe rare case worth a look: 70043 from an IP where the same user had no successful sign-in in the previous 30 days.
let lookback = 30d;let knownUserIPs = union (SigninLogs | project TimeGenerated, UserPrincipalName, IPAddress, ResultType), (AADNonInteractiveUserSignInLogs | project TimeGenerated, UserPrincipalName, IPAddress, ResultType) | where TimeGenerated > ago(lookback) | where ResultType == "0" | distinct UserPrincipalName, IPAddress;AADNonInteractiveUserSignInLogs| where TimeGenerated > ago(1d)| where ResultType == "70043"| join kind=leftanti knownUserIPs on UserPrincipalName, IPAddress| extend Location = parse_json(LocationDetails)| project TimeGenerated, UserPrincipalName, IPAddress, Country = tostring(Location.countryOrRegion), AppDisplayName, UserAgent, ResultDescription| sort by TimeGenerated descResultType is a string column, so compare it with "70043", not 70043. LocationDetails is a string in this table, hence parse_json. Non-interactive rows are aggregated when application, user, IP address, status and resource match, so row counts are not request counts.
How does Conditional Access affect it?
Section titled “How does Conditional Access affect it?”- The cause is a Conditional Access session control: sign-in frequency. Microsoft’s default, with no such policy, is “a rolling window of 90 days.”
- A shorter interval means more 70043 rows and more prompts. Microsoft warns: “Triggering reauthentication too frequently can increase security friction to a point that it causes users to experience MFA fatigue and open the door to phishing.”
- The re-authentication after a 70043 is a normal sign-in. It goes through MFA and the rest of your Conditional Access policies.
How do I fix AADSTS70043?
Section titled “How do I fix AADSTS70043?”For the user: sign in again when the app asks.
For admins:
- Nothing is broken. If users complain about too many prompts, check which policy sets the interval with the first query and the policy list on the matching interactive sign-in.
- Reserve short sign-in frequency intervals for high-risk apps, users or unmanaged devices, rather than everyone.
- If the second query returns a row you can’t explain, treat the user’s tokens as exposed: revoke sessions and check the user’s recent sign-ins.