Hero Banner

Multi-Factor Authentication (MFA)

Learn and ask questions on how to implement MFA

Visitor 1

OAuth Refresh token has expired after 90 days

We have encountered an issue on our live environment:

The Multi Factor Authentication does not work anymore.


We try to authenticate using an OAuth Refresh Token (this authentication mechanism has been recommended by the Yammer group "Partner Center Security Guidance", which now has been closed).

But since today, this authentication does not work anymore, but we get the following error message:
invalid_grant: AADSTS700082: The refresh token has expired due to inactivity. The token was issued on 2019-01-02T09:19:53.5422744Z and was inactive for 90.00:00:00.:


But I am absolutely sure that this refresh token has been successfully used yesterday.


The Microsoft documentation https://docs.microsoft.com/en-us/graph/auth-overview says that an OAuth Refresh token should only expired if it has been inactive for 90 days. But our tokens were used. Therefore the tokens should not expire!


Why do we now have a live incident? What went wrong?


Please not that we are selling in 12 different markets, and therefore have 12 different partner accounts, and therefore 24 different OAuth refresh tokens (one for the live environment and one for the sandbox). Therefore it is not this easy to update the 24 OAuth refresh tokens.


What can we do to avoid similar production incidents in the future?


We are regularily using the refresh tokens to get new access tokens. We do this using the call "POST /{tenant}/oauth2/token grant_type=refresh_token&refresh_token=..." (see https://docs.microsoft.com/en-us/azure/active-directory/develop/v1-protocols-oauth-code). The response of this call not only contains the access token, but also a new refresh token. At the moment, we ignore the new refresh token that is returned. Should we store and use the new refresh token that is returned by this call, or would the new refresh token also expire at the same time?


Does Microsoft offer a way to find out the expiry time or the issued-at-date of a refresh token?

Level 1 Contributor

When you access a mailbox of a specific user via a background service using MS Graph, the token will expire after 90 days since Graph does not return a refresh token (learned from experience).

Using administrator consent should resolve this issue, but the only choice is to get access to ALL mailboxes of the organization. This is way to great a security risk for this task.


Does anybody know a middle ground for this?
Is there a way to get the refresh token when using user consent, or limit admin consent to 1 mailbox?

Level 1 Contributor

Note that I use AcquireTokenSilent from the Microsoft.Identity.Client library.

Level 2 Contributor

@idwilliamsThanks for the clarification.


It is a bit sad that we cannot really do much about it currently but if we could get them to publish new policy to allow us to increase or remove the expiration - that would be lovely.


I know you said that you will update us here but can you also send and update on the Yammer group? 🙂


Thanks for looking into it as well mate... really appreciate the help!



Visitor 1

FYI I have found another cause of this error.

The AdalTokenCache.cs file generated by the MVC5 template seems to have had a bug in the past, which has now been fixed.

The bug is in the AfterAccessNotification method where an "if Cache == null" check is missing.

It may be down to whether you choose single tenant / multi tenant when creating your initial project, but either way I've just googled "adaltokencache.cs" and got examples of each:


1. This one contains the bug.



2. This one works correctly.



The bug causes multiple copies of a user's accesstoken/refreshtoken to be stored in the database - but because of the "FirstOrDefault" on retrieval, only the earliest one stored is ever retrieved - meaning after 90 days the refresh token expires and breaks the user access to the application.


Level 2 Contributor

@idwilliams  Thanks for getting back to us and for clarification.


In this case the documentation is wrong and should be updated... Also, are there any plans to allow us to extend this 90 days period via custom policy?


Currently based on somebody else's recommendation I automated the "refresh" of refresh token but I still think it is a silly thing to do and we should be allowed to keep it until revoked when it is constantly being used...


@cblackuk this is something that will need to be explored with the Azure AD team. I know they are currently planning a replacement for the policies they have available for managing tokens. However, I do not know any details regarding what exactly they are planning at this time. Once I learn more I will be sure to update this thread.

Level 3 Contributor

Ok. To understand clearly. Every time I request access token I actually will get new refresh token correct?

This new refresh token is valid but also the previous before the request also continues to be valid?

Some more questions:

In Azure AD MFA there is setting:

Allow users to remember multi-factor authentication on devices they trust
Days before a device must re-authenticate (1-60):

If that is enabled this actually restricts the validity of the token not to 90 days but to whatever is set. Is this bug or undocumented design?


Can we also get some reccomendation how often we should replace the refresh token? Every day? Every week? Every month?

Level 2 Contributor

Literally had the same issue just now:


AADSTS700082: The refresh token has expired due to inactivity. The token was issued on 2019-01-25T11:59:32.0690372Z and was inactive for 90.00:00:00.
Trace ID: 8856fa3c-d840-426a-85b4-4954e16c2600
Correlation ID: 122975b3-9650-47da-bed3-a3f6e11bca35
Timestamp: 2019-04-25 16:38:07Z


This is a massive issue from a CSP perspective.


The token is being used to get access tokens like 500 times a day and yet it was "inactive" for 90 days.


Can somebody comment on this please?


@cblackukand @stan 


This is happening because the refresh token has expired. The error being returned is a bit misleading and I believe that has caused some confusion. To better explain what is happening and what can be done it is important to understand that a single refresh token is only valid for 90 days. This means you can either perform the consent process every 90 days or implement the appropriate automation. Each time you request a new token from Azure AD a new refresh token is returned as well. If you were looking to automate the refresh of the refresh token, you would want to replace the existing refresh token value with a new one returned when you request a new access token on a set interval. Some partners are doing this once a week while others are doing it once a month. I hope that this helps!  

Visitor 1

Same thing happened here on Monday.  The documentation is obviously not entirely correct, as the lifespan of the refresh token is fixed at 90 days, no matter how much it is used.  In order to have token based authentication working for more than the initial 90 days, you need to periodically refresh your token store with new refresh tokens.


As long as your current tokens have not expired, you can get new ones by calling the New-PartnerAccessToken cmdlet and update your store with the refreshtoken part of the token returned by the cmdlet.  It is a good idea to write a scheduled job performing this task for all your tenants on a regular basis.


Unfortunately, I believe you have to go through the consent process again in order to get valid refresh tokens again and get the whole thing rolling.  I just completed this for our 34 customer tenants, and yes: It was deadly boring 🙂

Level 3 Contributor

@idwilliams  Can we get answer on this thread also? Why is this happening?

Visitor 1

We have exactly the same problem.


Would someone from MS please look into this issue? The MS specification for the refresh token does NOT match the implementation. This needs to be fixed asap.