dotnet/aspnetcore · error
Failed to retrieve token, no account found.
Error message
Failed to retrieve token, no account found.
What it means
Thrown by AuthenticationService.getTokenCore() in the MSAL interop (AuthenticationService.ts:191) when getAccount() returns null. Token acquisition requires a signed-in account to build the silent request; with no account in MSAL's cache (neither a stored _account nor any account from getAllAccounts()), the service cannot request a token and throws. The outer getAccessToken() wrapper catches this and converts it to a RequiresRedirect result.
Source
Thrown at src/Components/WebAssembly/Authentication.Msal/src/Interop/AuthenticationService.ts:191
async getAccessToken(request?: AccessTokenRequestOptions): Promise<AccessTokenResult> {
try {
this.trace('getAccessToken', request);
const newToken = await this.getTokenCore(request?.scopes);
return {
status: AccessTokenResultStatus.Success,
token: newToken
};
} catch (e) {
return {
status: AccessTokenResultStatus.RequiresRedirect
};
}
}
async getTokenCore(scopes?: string[]): Promise<AccessToken | undefined> {
const account = this.getAccount();
if (!account) {
throw new Error('Failed to retrieve token, no account found.');
}
const silentRequest = {
redirectUri: this._settings.auth?.redirectUri,
account: account,
scopes: scopes || this._settings.defaultAccessTokenScopes
};
this.debug(`Provisioning a token silently for scopes '${silentRequest.scopes}'`)
this.trace('_msalApplication.acquireTokenSilent', silentRequest);
const response = await this._msalApplication.acquireTokenSilent(silentRequest);
this.trace('_msalApplication.acquireTokenSilent-response', response);
if (response.scopes.length === 0 || response.accessToken === '') {
throw new Error('Scopes not granted.');
}
const result = {View on GitHub (pinned to 294cab2f9b)
Solutions
- Trigger an interactive sign-in flow (signIn/redirect) before requesting access tokens — verify isAuthenticated first.
- Ensure redirectUri in MSAL settings matches the registered application redirect exactly and that the hash is processed on return (handleRedirectPromise).
- Check that third-party cookies / partitioned storage are not blocking MSAL's silent cache reads; fall back to interactive acquisition.
- Call getAccessToken with appropriate interaction so the framework can prompt rather than fail silently.
Example fix
// before
const token = await authService.getAccessToken({ scopes: ['api'] });
// after
if (!await authService.isAuthenticated()) {
await authService.signIn({ /* interaction */ });
}
const token = await authService.getAccessToken({ scopes: ['api'] }); Defensive patterns
Strategy: try-catch
Validate before calling
async function ensureAccount(authService: AuthenticationService): Promise<boolean> {
return Boolean(authService.getAccount());
} Try / catch
try {
const token = await authService.getTokenCore(scopes);
} catch (e) {
if (/no account found/i.test(e.message)) {
await authService.signIn({ ... }); // interactive sign-in
} else { throw e; }
} Prevention
- Ensure sign-in completes before calling getAccessToken.
- Handle the RequiresRedirect result from getAccessToken to trigger interactive sign-in.
- Verify redirectUri matches the app registration.
- Watch for third-party cookie / partitioned storage blocking silent SSO.
When it happens
Trigger: Calling getAccessToken()/getTokenCore() before the user has signed in, after sign-out cleared the account, after the MSAL cache expired/was cleared, or when the redirect/parse of the auth response failed so no account was established. Also when the configured authority/loginHint does not match any cached account.
Common situations: App boots and requests an access token before completing the sign-in flow. User cleared browser storage or the session expired. The MSAL redirect handling did not parse the URL hash into an account (wrong redirectUri, blocked third-party cookies/IFrame storage, or a failed silent SSO). Multiple tabs interfering with the MSAL cache.
Related errors
- Scopes not granted.
- Could not load settings from '${settings.configurationEndpoi
- The server responded with status ${response.status}.
- Authorization requires a cascading parameter of type Task<Au
- There is no file with ID ${fileId}. The file list may have c
AI-assisted analysis of dotnet/aspnetcore@294cab2f9b (2026-08-06).
Data as JSON: /api/errors/cfac5b69bca9a741.
Report an issue: GitHub.