AADSTS700081: Refresh token reached its maximum lifetime (fix)
Short answer: AADSTS700081 means the app tried to use a refresh token that is past its maximum lifetime. Users report it in single-page apps, where Microsoft caps refresh tokens at 24 hours. Microsoft's error reference doesn't list it. It is an expected part of the token lifecycle with low attack value. The app must send the user through sign-in again.
Fix: User: sign in to the app again; a page reload is often enough. Developer: treat it as sign-in needed. With MSAL.js, catch it from `acquireTokenSilent` and fall back to `acquireTokenRedirect` or `acquireTokenPopup`. Admin: nothing to change; the SPA lifetime can't be extended. Full steps
| Code | AADSTS700081 |
|---|---|
| In Microsoft's error reference | No (checked ). Wording on this page is what Entra returned or what users report. |
| Category | Tokens and sessions |
| Type | Interrupt (an expected extra step, not a failure) |
| Attack signal | Low: usually configuration or user error |
| Microsoft lookup | login.microsoftonline.com/error?code=700081 |
What does AADSTS700081 mean?
Section titled “What does AADSTS700081 mean?”Microsoft’s error code reference doesn’t list AADSTS700081 (checked 30 October 2026).
The wording below comes from a user report. A developer on the MSAL.js GitHub repository posted:
AADSTS700081: The refresh token has expired due to maximum lifetime. The token was issued on 2021-07-22T15:38:26.0767832+00:00 and the maximum allowed lifetime for this application is 1.00:00:00.
The app was a single-page app (SPA) using MSAL.js 2 and MSAL React. It showed up during an acquireTokenSilent call. A commenter in the thread said this error should be handled inside acquireTokenSilent and not returned to the app. 1.00:00:00 is one day.
Microsoft documents the 24-hour cap, without the code number. Its refresh token page:
Refresh tokens sent to a redirect URI registered as
spaexpire after 24 hours. Additional refresh tokens acquired using the initial refresh token carry over that expiration time, so apps must be prepared to rerun the authorization code flow using an interactive authentication to get a new refresh token every 24 hours.
The same page lists 24 hours for single-page apps, 24 hours for apps that use the email one-time passcode flow, and 90 days for all other scenarios.
So rotating the refresh token doesn’t help. Each new refresh token inherits the original expiry. When it passes, the app has to start a new sign-in.
Microsoft’s error reference lists a code for the same situation, AADSTS700084: “The refresh token was issued to a single page app (SPA), and therefore has a fixed, limited lifetime of {time}, which can’t be extended.” Our reading: 700081 and 700084 describe the same cap. Which code you get in which case isn’t documented. The GitHub report is from 2021, so 700084 may be the newer wording.
Don’t confuse it with 700082, which is a refresh token that expired from inactivity. 700081 is about total age, however active the user was.
Is it an attack?
Section titled “Is it an attack?”No. It is the token lifecycle working as designed.
| Pattern | Likely meaning |
|---|---|
| SPA users get it once a day | The 24-hour cap. Expected. The app should redirect to sign-in. |
| Users see an error page instead of a quiet re-sign-in | Probably the app doesn’t handle the error (unconfirmed). |
| One user, many rows, no success after | The app keeps retrying the expired token. A bug in the app. |
| Expired tokens presented from IPs your users don’t use | Possibly someone replaying an old stolen token (unconfirmed). Rare; check the IPs. |
How do I find it in my logs (KQL)?
Section titled “How do I find it in my logs (KQL)?”Microsoft doesn’t document which sign-in table 700081 is logged in. Our reading: refresh token redemption is non-interactive, so AADNonInteractiveUserSignInLogs is the first place to look. Check where it lands:
union withsource=SourceTable SigninLogs, AADNonInteractiveUserSignInLogs, AADServicePrincipalSignInLogs| where TimeGenerated > ago(30d)| where ResultType in ("700081", "700084", "700082")| summarize Rows = count(), Users = dcount(UserPrincipalName) by SourceTable, ResultTypeWhich apps, and whether users recover. A user who hits 700081 and never succeeds on the same app that day points at an app that doesn’t fall back to sign-in:
let expired = union SigninLogs, AADNonInteractiveUserSignInLogs | where TimeGenerated > ago(7d) | where ResultType == "700081" | summarize FirstFail = min(TimeGenerated) by UserPrincipalName, AppId, AppDisplayName;let successes = union SigninLogs, AADNonInteractiveUserSignInLogs | where TimeGenerated > ago(7d) | where ResultType == "0" | summarize LastSuccess = max(TimeGenerated) by UserPrincipalName, AppId;expired| join kind=leftouter successes on UserPrincipalName, AppId| where isnull(LastSuccess) or LastSuccess < FirstFail| summarize UsersNotRecovering = dcount(UserPrincipalName) by AppDisplayName, AppId| sort by UsersNotRecovering descNon-interactive rows are aggregated, so counts are not request counts.
How do I fix AADSTS700081?
Section titled “How do I fix AADSTS700081?”For the user: sign in to the app again. A page reload is often enough. If you see this every day, the app should handle it for you; tell its owner.
For developers:
- Treat it as “sign-in needed”, not as a failure. Microsoft: “apps must be prepared to rerun the authorization code flow using an interactive authentication to get a new refresh token every 24 hours.”
- With MSAL.js, catch the error from
acquireTokenSilentand fall back toacquireTokenRedirectoracquireTokenPopup. In the GitHub thread, a commenter said MSAL should fall back to a hidden iframe when the refresh token expires. The reporter’s fix was letting the app’s page load in an iframe (X-Frame-Options: SAMEORIGIN). - Expect silent renewal to fail in browsers that block third-party cookies. Microsoft: “The browser must visit the sign-in page in a top-level frame to show the login session.”
- If you need refresh tokens that live longer, the client isn’t an SPA. Redeem tokens on a backend registered as a Web app. Don’t move SPA tokens to a server; that gives 9002327.
For admins: nothing to change in the tenant. Microsoft says the SPA lifetime is fixed and “can’t be extended” (700084 wording). Filter the code out of failure dashboards.
Related codes
- AADSTS700082: The refresh token has expired due to inactivity
- AADSTS70008: The refresh token has expired or was revoked
- AADSTS50058: Session information isn't sufficient for single sign-on
- AADSTS9002327: SPA token redeemed without a browser Origin
Sources
- Microsoft Entra authentication and authorization error codes
- GitHub: Failed authentication. AADSTS700081: The refresh token has expired due to maximum lifetime (microsoft-authentication-library-for-js #3931)
- Refresh tokens in the Microsoft identity platform
- Microsoft identity platform and OAuth 2.0 authorization code flow
- SigninLogs table reference (Azure Monitor)