# AADSTS700081: Refresh token reached its maximum lifetime (fix)

Canonical: https://brambrinkmeier.com/entra/aadsts/700081/
By Bram Brinkmeier. JSON: https://brambrinkmeier.com/api/aadsts/700081.json

**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.

| Field | Value |
|---|---|
| Code | AADSTS700081 |
| Category | Tokens and sessions |
| Type | Interrupt (an expected extra step, not a failure) |
| Attack signal | Low: usually configuration or user error |
| In Microsoft's error reference | No (checked 2026-10-30) |
| Verification | documentation |
| Last updated | 2026-10-30 |

## What does AADSTS700081 mean?

Microsoft's [error code reference](https://learn.microsoft.com/entra/identity-platform/reference-error-codes) 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 `spa` expire 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](https://brambrinkmeier.com/entra/aadsts/700082/), which is a refresh token that expired from **inactivity**. 700081 is about **total age**, however active the user was.

## 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)?

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:

```kusto
union withsource=SourceTable SigninLogs, AADNonInteractiveUserSignInLogs, AADServicePrincipalSignInLogs
| where TimeGenerated > ago(30d)
| where ResultType in ("700081", "700084", "700082")
| summarize Rows = count(), Users = dcount(UserPrincipalName) by SourceTable, ResultType
```

Which 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:

```kusto
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 desc
```

Non-interactive rows are aggregated, so counts are not request counts.

## 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:**
1. 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."*
2. With MSAL.js, catch the error from `acquireTokenSilent` and fall back to `acquireTokenRedirect` or `acquireTokenPopup`. 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`).
3. 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."*
4. 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](https://brambrinkmeier.com/entra/aadsts/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.

## Evidence

Not in Microsoft's error reference and not reproduced in the lab; built from lab results, other Microsoft pages and user reports, which the page names.

## Sources

1. [Microsoft Entra authentication and authorization error codes](https://learn.microsoft.com/entra/identity-platform/reference-error-codes)
2. [GitHub: Failed authentication. AADSTS700081: The refresh token has expired due to maximum lifetime (microsoft-authentication-library-for-js #3931)](https://github.com/AzureAD/microsoft-authentication-library-for-js/issues/3931)
3. [Refresh tokens in the Microsoft identity platform](https://learn.microsoft.com/en-us/entra/identity-platform/refresh-tokens)
4. [Microsoft identity platform and OAuth 2.0 authorization code flow](https://learn.microsoft.com/entra/identity-platform/v2-oauth2-auth-code-flow)
5. [SigninLogs table reference (Azure Monitor)](https://learn.microsoft.com/en-us/azure/azure-monitor/reference/tables/signinlogs)

## Related codes

[AADSTS700082](https://brambrinkmeier.com/entra/aadsts/700082/), [AADSTS70008](https://brambrinkmeier.com/entra/aadsts/70008/), [AADSTS50058](https://brambrinkmeier.com/entra/aadsts/50058/), [AADSTS9002327](https://brambrinkmeier.com/entra/aadsts/9002327/)

## License and citation

CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/). CC BY 4.0 covers the author's own text and classification fields. Quoted Microsoft error wording belongs to Microsoft, is quoted with its source and can change.

Cite as: Bram Brinkmeier, "AADSTS700081: Refresh token reached its maximum lifetime (fix)", https://brambrinkmeier.com/entra/aadsts/700081/ (CC BY 4.0), last updated 2026-10-30.
