Skip to content

AADSTS50089: Flow token expired, sign in again (fix)

Short answer: AADSTS50089 means a sign-in failed because a token that was part of the sign-in had expired. Microsoft calls it expected: auth codes, refresh tokens and sessions expire or get revoked, and the app asks the user to sign in again. It has low attack value. Filter it out of failure dashboards and look only at users who can't get past it.

Fix: Nothing to fix: the token expired as designed. User: sign in again. If it keeps happening, close the app or tab and start a fresh sign-in. Developer: treat 50089 as 'start a new sign-in' and redeem auth codes immediately. Admin: exclude 50089 from failure counts and spray rules. Full steps

At a glance
CodeAADSTS50089
CategoryTokens and sessions
TypeInterrupt (an expected extra step, not a failure)
Attack signalLow: usually configuration or user error
Microsoft lookuplogin.microsoftonline.com/error?code=50089

Microsoft’s description:

Authentication failed due to flow token expired. Expected - auth codes, refresh tokens, and sessions expire over time or are revoked by the user or an admin. The app will request a new login from the user.

The reference table gives this code no PascalCase name.

Microsoft doesn’t define “flow token” anywhere we could find. Our reading is that it refers to the state Entra keeps for a sign-in in progress, so a sign-in page left open too long before the user finishes would produce 50089. The description itself names three things that expire: auth codes, refresh tokens and sessions. Some documented lifetimes:

  • Authorization codes are short lived. The authorization code flow reference: “Typically, they expire after about 1 minute.”
  • Refresh tokens have a default Max Inactive Time of 90 days.
  • Session tokens: “Non-persistent session tokens have a Max Inactive Time of 24 hours; persistent session tokens have a Max Inactive Time of 90 days.”

Several close relatives cover specific cases of “your old token or session no longer counts”:

  • 50133: the session is invalid after a password change or expiry.
  • 50173: the grant was revoked, for example after a password reset.
  • 70043: a Conditional Access sign-in frequency policy refused the refresh token.

For a comparison of the codes behind repeated sign-in prompts, see why a user is asked to sign in again.

No. Microsoft’s description starts with “Expected”. The sign-in fails, nothing is issued, and the app starts over.

Pattern Likely meaning
A few 50089 rows per user, each followed by a success A token or sign-in step expired and the user signed in again. Benign.
50089 for many users of one app, all at the same time of day Our interpretation: users who leave the sign-in page or app open overnight and continue the next morning. Benign.
50089 for one user, repeating several times a day, often with no success after Something on that device keeps presenting an expired token or session. Clear the app’s cached sign-in or browser state.
50089 together with 50133 or 50173 for the same user A password change or revocation is working its way through the user’s sessions. Benign if you know about the change.

There is no documented attack pattern for 50089. An expired token gets the sender nothing. Keep it out of password spray detections and failure-rate thresholds.

Microsoft doesn’t document which sign-in table 50089 is logged in. Start by checking where it lands in your workspace:

union withsource=SourceTable SigninLogs, AADNonInteractiveUserSignInLogs
| where TimeGenerated > ago(7d)
| where ResultType == "50089"
| summarize Rows = count(), Users = dcount(UserPrincipalName) by SourceTable

Which apps and client types produce it:

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

Users who hit 50089 again and again without a success afterwards on the same app the same day. These are the ones worth a support ticket:

let expired =
union SigninLogs, AADNonInteractiveUserSignInLogs
| where TimeGenerated > ago(1d)
| where ResultType == "50089"
| summarize FirstFail = min(TimeGenerated), Fails = count() by UserPrincipalName, AppId, AppDisplayName;
let successes =
union SigninLogs, AADNonInteractiveUserSignInLogs
| where TimeGenerated > ago(1d)
| where ResultType == "0"
| summarize LastSuccess = max(TimeGenerated) by UserPrincipalName, AppId;
expired
| join kind=leftouter successes on UserPrincipalName, AppId
| where isnull(LastSuccess) or LastSuccess < FirstFail
| where Fails >= 5
| project UserPrincipalName, AppDisplayName, Fails, FirstFail
| sort by Fails desc

The threshold of 5 is a starting point; tune it to your tenant. Non-interactive rows are aggregated when application, user, IP address, status and resource match, so Fails counts rows there, not requests. ResultType is a string column, so compare it with "50089", not 50089.

  • 50089 is not a Conditional Access block. No policy causes it directly.
  • Session lifetime is now controlled with Conditional Access. Microsoft: refresh and session token lifetimes “are no longer configurable through token lifetime policies” and “To control how frequently users are required to sign in, use Conditional Access sign-in frequency instead.”
  • A sign-in frequency policy that refuses a refresh token shows up as 70043, not 50089. If users complain about frequent prompts, check for 70043 first.
  • Microsoft warns that combining Remember MFA on trusted devices with sign-in frequency “might prompt users unexpectedly.”

For the user: sign in again. If it keeps happening, close the app or browser tab completely and start a fresh sign-in instead of continuing an old one.

For developers: treat 50089 as “start a new sign-in”, not as a fatal error. Microsoft says “The app will request a new login from the user.” Redeem authorization codes immediately; they typically expire after about a minute. Don’t build logic on the code number itself. Microsoft notes that “Apps that take a dependency on text or error code numbers will be broken over time.” React to the OAuth error value instead.

For admins:

  1. Nothing is broken. Exclude "50089" from failure counts and spray detections.
  2. Use the third query for users stuck in a loop. Clear the app’s cached sign-in on their device or browser.
  3. If many users get unexpected sign-in prompts, review your Conditional Access session controls (sign-in frequency, persistent browser session) and turn off Remember MFA on trusted devices if you use sign-in frequency.
  • AADSTS50133: Session invalid after password change or expiry
  • AADSTS50173: Grant expired because it was revoked
  • AADSTS70043: Refresh token expired due to sign-in frequency checks
  • AADSTS700082: The refresh token has expired due to inactivity
  • AADSTS50058: Session information isn't sufficient for single sign-on

Sources

  1. Microsoft Entra authentication and authorization error codes
  2. Configurable token lifetimes in the Microsoft identity platform
  3. Configure adaptive session lifetime policies
  4. Microsoft identity platform and OAuth 2.0 authorization code flow
  5. Non-interactive user sign-ins