While implementing silent token acquisition using MSAL.js 2.0 (msal-browser) you may come across an error like
BrowserAuthError: monitor_window_timeout : Token acquisition in popup failed due to timeout
This error might also keep changing to the actual error that is being returned (in my case it was the InteractionRequiredAuthError) on every refresh.
Let’s understand what happens here in detail :-
When you try to implement silent acquisition of token using either acquireTokenSilent or the ssoSilent variations, the token is returned in a hidden iframe. Any error resulting from this fetch is also returned in this iframe redirect.
msal-browser continuously polls the iframe to get the hash content i.e. the error / token / code being returned as a part of the authentication response. This polling mechanism has a default timeout of 6 seconds. If the redirect is not intercepted within this timeout then it throws the error above.
If you run a fiddler trace, you should be able to see the actual response being returned. In my case, it was the
InteractionRequiredAuthError: login_required: AADSTS50058: A silent sign-in request was sent but no user is signed in.
Now, the fiddler trace reveals that the response is always a redirect with query string as error: login_required which means I had to fallback to an interactive login approach. It was hard to implement a try / catch for the specific error as sometimes (randomly) it would return BrowserAuthError: monitor_window_timeout: OR InteractionRequiredAuthError
However, to resolve the BrowserAuthError: monitor_window_timeout error, you can modify the default timeout in the msal config.
Specify the iframeHashTimeout key under the system config options while initializing msal. I had increased the timeout from 6s to 10s.
The iframehashtimeout specifies the time to wait for the iframe authentication to resolve in milliseconds.
const msalConfig: msal.Configuration = {
auth: {
clientId: "xxxxxxx",
authority:
"xxxxxxx",
redirectUri:
"xxxxxx",
},
system: {
iframeHashTimeout: 10000,
},
};
Update based on @George’s comment below :
This issue might also occur when apps use their homepage as redirect URI. The resolution would be to point the redirect URI to a blank page. It can be a blank HTML page as well. Details of the issue here.
This change always returned the actual error which meant I could happily go back and implement an appropriate error handling mechanism based on the error returned. For additional configuration options have a look at the Microsoft docs.
I have a similar issue with ssoSilent call but it consistently returns window timeout error. Sometimes ssoSilent works but when it doesn’t it triggers the timeout error. Checking the ssoSilent http response I see the callback error saying interactive login is required though. I tried increasing the timeout like you suggested but I am still getting the timeout error
Hey George,
Do you get the timeout issue each time you refresh or is it intermittent? In my case, at times I used to get either the timeout error or interaction required randomly on each refresh.
It’s an intermittent issue I experience on Chrome 85 when I have the app deployed with an Nginx server on an Azure VM
I don’t have this issue when I run the app locally on my laptop though.
My only workaround at this point is to tell users to use Firefox
Did you try debugging it all the way to the msal-browser library? The methods that check for the iframe redirect using setInterval?
This should help you get closer to the issue and its resolution.
I opened a github issue for this and a contributor came back with a workaround:
https://github.com/AzureAD/microsoft-authentication-library-for-js/issues/2263#issuecomment-691191179
okay! This is unusual, in my case, the redirect URI is the same page where the app is added (not the homepage of my site though). Thank you for getting back George. I will edit my post to reflect this issue and resolution as well.
This article helped me fix issue in edge. I was using homepage as redirect URI. The resolution would be to point the redirect URI to a blank page.
Hey, I’m running into the same issue. I’m using the Typescript version of this library with Sharepoint (sp-http-base). I’m having trouble figuring out the syntax to set the iframe timeout to a different value. Currently I’m making my POST request that I think is triggering this with the following:
const response = await this.aadHttpClient.post(
url.href,
AadHttpClient.configurations.v1, //what is the syntax for me to use this same config, but with higher timeout value?
{},
);
Would you be able to provide any assistance?