acquireTokenSilent throws no_tokens_found: No refresh token found in the cache. when called concurrently
Core Library
MSAL Node (@azure/msal-node)
Core Library Version
3.6.2
Wrapper Library
MSAL Node Extensions (@azure/msal-node-extensions)
Wrapper Library Version
1.5.16
Public or Confidential Client?
Public
Description
I'm using @azure/msal-node library with @azure/msal-node-extensions (PersistenceCachePlugin) in an electron project. I observed strange behavior when sometimes the app couldn't fetch the access token between reloads. I tried to isolate the problem and found out that when acquireTokenSilent is called concurrently (e.g. by electron renderer process calling main code via ipc), sometimes it is unable to find the tokens in the cache. I created a repository where it's easy to reproduce this issue gawronA/msal-node-get-access-token.
Error Message
Error occurred in handler for 'getAccessToken': InteractionRequiredAuthError: no_tokens_found: No refresh token found in the cache. Please sign-in.
at createInteractionRequiredAuthError (C:\Users\Z0083446\repos\msal-node-get-access-token\node_modules@azure\msal-node\lib\msal-node.cjs:6449:12)
at RefreshTokenClient.acquireTokenWithCachedRefreshToken (C:\Users\Z0083446\repos\msal-node-get-access-token\node_modules@azure\msal-node\lib\msal-node.cjs:7357:19)
at C:\Users\Z0083446\repos\msal-node-get-access-token\node_modules@azure\msal-node\lib\msal-node.cjs:5039:16
at RefreshTokenClient.acquireTokenByRefreshToken (C:\Users\Z0083446\repos\msal-node-get-access-token\node_modules@azure\msal-node\lib\msal-node.cjs:7346:211)
at PublicClientApplication.acquireTokenSilent (C:\Users\Z0083446\repos\msal-node-get-access-token\node_modules@azure\msal-node\lib\msal-node.cjs:10308:47)
at async C:\Users\Z0083446\repos\msal-node-get-access-token\main.js:76:26
at async Session.
MSAL Logs
[Mon, 07 Jul 2025 21:04:49 GMT] : [] : @azure/[email protected] : Info - getTokenCache called [Mon, 07 Jul 2025 21:04:49 GMT] : [] : @azure/[email protected] : Trace - getAllAccounts called [Mon, 07 Jul 2025 21:04:49 GMT] : [] : @ : Info - Executing before cache access [Mon, 07 Jul 2025 21:04:49 GMT] : [] : @azure/[email protected] : Info - getTokenCache called [Mon, 07 Jul 2025 21:04:49 GMT] : [] : @azure/[email protected] : Trace - getAllAccounts called [Mon, 07 Jul 2025 21:04:49 GMT] : [] : @ : Info - Executing before cache access [Mon, 07 Jul 2025 21:04:49 GMT] : [] : @ : Info - Tried to unlock but lockfile does not exist [Mon, 07 Jul 2025 21:04:49 GMT] : [] : @ : Info - Pid 2220 afterCacheAccess released lock [Mon, 07 Jul 2025 21:04:49 GMT] : [] : @azure/[email protected] : Trace - Getting in-memory cache [Mon, 07 Jul 2025 21:04:49 GMT] : [] : @azure/[email protected] : Trace - Getting cache key-value store [Mon, 07 Jul 2025 21:04:49 GMT] : [87616bdf-ff0a-4a57-bd2f-427c179a8e2d] : @azure/[email protected] : Trace - CacheManager - getAccessToken called [Mon, 07 Jul 2025 21:04:49 GMT] : [87616bdf-ff0a-4a57-bd2f-427c179a8e2d] : @azure/[email protected] : Info - CacheManager:getAccessToken - No token found [Mon, 07 Jul 2025 21:04:49 GMT] : [87616bdf-ff0a-4a57-bd2f-427c179a8e2d] : @azure/[email protected] : Info - Token refresh is required due to cache outcome: 2 [Mon, 07 Jul 2025 21:04:49 GMT] : [] : @azure/[email protected] : Trace - Retrieving all cache keys [Mon, 07 Jul 2025 21:04:49 GMT] : [] : @azure/[email protected] : Trace - Getting cache key-value store [Mon, 07 Jul 2025 21:04:49 GMT] : [87616bdf-ff0a-4a57-bd2f-427c179a8e2d] : @azure/[email protected] : Trace - Executing function refreshTokenClientAcquireTokenWithCachedRefreshToken [Mon, 07 Jul 2025 21:04:49 GMT] : [87616bdf-ff0a-4a57-bd2f-427c179a8e2d] : @azure/[email protected] : Trace - Executing function cacheManagerGetRefreshToken [Mon, 07 Jul 2025 21:04:49 GMT] : [] : @azure/[email protected] : Trace - CacheManager - getRefreshToken called [Mon, 07 Jul 2025 21:04:49 GMT] : [] : @azure/[email protected] : Trace - Getting in-memory cache [Mon, 07 Jul 2025 21:04:49 GMT] : [] : @azure/[email protected] : Trace - Getting cache key-value store [Mon, 07 Jul 2025 21:04:49 GMT] : [] : @azure/[email protected] : Info - CacheManager:getRefreshToken - No refresh token found. [Mon, 07 Jul 2025 21:04:49 GMT] : [87616bdf-ff0a-4a57-bd2f-427c179a8e2d] : @azure/[email protected] : Trace - Returning result from cacheManagerGetRefreshToken [Mon, 07 Jul 2025 21:04:49 GMT] : [87616bdf-ff0a-4a57-bd2f-427c179a8e2d] : @azure/[email protected] : Trace - Error occurred in refreshTokenClientAcquireTokenWithCachedRefreshToken [Mon, 07 Jul 2025 21:04:49 GMT] : [87616bdf-ff0a-4a57-bd2f-427c179a8e2d] : @azure/[email protected] : Trace - {"errorCode":"no_tokens_found","errorMessage":"No refresh token found in the cache. Please sign-in.","subError":"","name":"InteractionRequiredAuthError","timestamp":"","traceId":"","correlationId":"","claims":""} [Mon, 07 Jul 2025 21:04:49 GMT] : [] : @azure/[email protected] : Trace - Getting cache key-value store [Mon, 07 Jul 2025 21:04:49 GMT] : [] : @azure/[email protected] : Trace - Setting cache key value store [Mon, 07 Jul 2025 21:04:49 GMT] : [] : @ : Info - Executing after cache access [Mon, 07 Jul 2025 21:04:49 GMT] : [] : @ : Info - Msal in-memory cache has not changed. Did not write to persistence [Mon, 07 Jul 2025 21:04:49 GMT] : [] : @azure/[email protected] : Trace - Getting cache key-value store [Mon, 07 Jul 2025 21:04:49 GMT] : [] : @azure/[email protected] : Trace - Setting cache key value store [Mon, 07 Jul 2025 21:04:49 GMT] : [] : @ : Info - Executing after cache access [Mon, 07 Jul 2025 21:04:49 GMT] : [] : @ : Info - Msal in-memory cache has not changed. Did not write to persistence
Network Trace (Preferrably Fiddler)
- [ ] Sent
- [ ] Pending
MSAL Configuration
{
auth: {
clientId: "<CLIENT_ID>",
authority: "<AUTHORITY>",
},
cache: {
cachePlugin: new PersistenceCachePlugin(persistence, lockOptions),
},
};
Relevant Code Snippets
https://github.com/gawronA/msal-node-get-access-token
Reproduction Steps
- Clone the repo gawronA/msal-node-get-access-token
- Set
<CLIENT_ID>and<AUTHORITY>inmain.js -
npm install -
npm start - Click the "Login" button to log in.
- After logging in, the access token is fetched every 200ms. Move the slider to 0s and observe the console output of main process. You'll see the error messages. Errors also appear in dev tools console.
Expected Behavior
Concurrent reads should wait if cache is busy and not result in no_tokens_found error.
Identity Provider
Entra ID (formerly Azure AD) / MSA
Browsers Affected (Select all that apply)
Chrome, Other
Regression
No response
Also affected by this issue. I can confirm that the description is accurate, as using semaphore as a temporary solution resolves it. Hopefully, this issue won't go stale.
Yes using a custom cache plugin on the first time i access the cache it works but it doesn't work after that
I'm also affected by the same issue. I initially call getAccounts which returns one or more accounts, and short after I call getAccounts again in order to get an access token, and the account list is empty. On later calls the list is populated again.
I use a FilePersistence as backing store for the PersistenceCache. My hunch is there's something with the call to beforeCacheAccess that occurs before the store is accessed which causes the store to be temporarily cleared/reset.