Skip to content

AADSTS700082: The refresh token has expired due to inactivity

Short answer: AADSTS700082 means an app tried to use a refresh token that expired because nobody used it for too long. Microsoft calls it an expected part of the token lifecycle, so it has low attack value. One useful reading: a stolen refresh token that sat unused long enough fails here too. Hunt it in AADNonInteractiveUserSignInLogs with ResultType == "700082".

At a glance
CodeAADSTS700082
Microsoft nameExpiredOrRevokedGrantInactiveToken
CategoryTokens and sessions
TypeFailure
Attack signalLow: usually configuration or user error
Where to lookAADNonInteractiveUserSignInLogs
Microsoft lookuplogin.microsoftonline.com/error?code=700082

ExpiredOrRevokedGrantInactiveToken: The refresh token has expired due to inactivity. The token was issued on {issueDate} and was inactive for {time}. Expected part of the token lifecycle - the user went an extended period of time without using the application, so the token was expired when the app attempted to refresh it.

A sibling in the same table, 70008 ExpiredOrRevokedGrant, reads “The refresh token has expired due to inactivity.”

The token wasn’t revoked and no policy fired. It simply sat unused until it expired. The message tells you when it was issued and how long it was inactive.

No. Microsoft’s own description says it is “Expected part of the token lifecycle”. Typical sources are a laptop that was off for weeks, an app the user rarely opens, or a phone that came back from a drawer.

Pattern Likely meaning
700082 from a user’s known device, then an interactive success The user came back to an app after a long break. Benign.
700082 from an IP or device the user hasn’t used recently Someone presented an old refresh token from an unfamiliar place. Reasoning, not a documented detection: if that token was stolen, the expiry is what stopped it. Worth a short look.
Steady 700082 from a service or shared device A client that holds tokens but rarely uses them. Configuration, not attack.

The useful negative example: a stolen refresh token is only valuable while it is used. One that the attacker left dormant long enough fails with 700082 rather than giving them access. That is the token lifetime working in your favour, not a detection you can rely on.

Baseline by app:

AADNonInteractiveUserSignInLogs
| where TimeGenerated > ago(7d)
| where ResultType == "700082"
| summarize Rows = count(), Users = dcount(UserPrincipalName) by AppDisplayName
| sort by Rows desc

700082 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 == "700082"
| join kind=leftanti knownUserIPs on UserPrincipalName, IPAddress
| extend Device = parse_json(DeviceDetail), Location = parse_json(LocationDetails)
| project TimeGenerated, UserPrincipalName, IPAddress,
Country = tostring(Location.countryOrRegion),
OS = tostring(Device.operatingSystem),
AppDisplayName, UserAgent, ResultDescription
| sort by TimeGenerated desc

Expect some benign hits here: a user who was away for more than the lookback period has no recent “known” IPs to match. ResultType is a string column, so compare it with "700082", not 700082. DeviceDetail and LocationDetails are strings in this table, hence parse_json.

  • No Conditional Access policy causes 700082. It is token inactivity, not a session control. If a sign-in frequency policy refused the token, you would see 70043 instead.
  • The interactive sign-in that follows goes through MFA and Conditional Access as normal.

For the user: sign in again.

For admins:

  1. Nothing to fix. Exclude 700082 from failure-rate dashboards, or it inflates them.
  2. If the second query returns an IP you can’t explain for a user, check that user’s other sign-ins from it. A token that failed here may have a sibling that didn’t.

Sources

  1. Microsoft Entra authentication and authorization error codes
  2. Non-interactive user sign-ins
  3. AADNonInteractiveUserSignInLogs table reference (Azure Monitor)