redis/node-redis · error · Error

Invalid token response

Error message

Invalid token response

What it means

`MSALIdentityProvider.requestToken()` calls the injected MSAL `getToken()` and requires the result to have both `accessToken` and `expiresOn`; if either is missing (or the result is null/undefined), it throws 'Invalid token response' rather than handing an incomplete token downstream. The subsequent `ttlMs` math (`expiresOn.getTime()`) would also throw on a non-Date, so the guard prevents that.

Solutions

  1. Verify MSAL configuration (clientId, tenant, authority, scopes, redirect).
  2. Ensure the credentials/account used for silent acquisition exist and are valid.
  3. Make the injected `getToken` reject (not resolve empty) on real failures so requestToken surfaces the underlying MSAL error.
  4. Clear/rebuild the MSAL token cache if corrupted.
Defensive patterns

Strategy: try-catch

Validate before calling

function isValidTokenResult(r: unknown): r is { accessToken: string; expiresOn: Date } {
  return !!r && typeof (r as any)?.accessToken === 'string' && (r as any)?.expiresOn instanceof Date;
}

Type guard

function isValidTokenResult(r: unknown): r is { accessToken: string; expiresOn: Date } {
  return !!r && typeof (r as any)?.accessToken === 'string' && (r as any)?.expiresOn instanceof Date;
}

Try / catch

try {
  return await provider.requestToken();
} catch (e) {
  if (String(e).includes('Invalid token response')) {
    // surface underlying MSAL error by retrying interactive acquisition, or rethrow with context
    throw new Error('MSAL returned an incomplete token; check scopes/credentials/account', { cause: e });
  }
  throw e;
}

Prevention

When it happens

Trigger: MSAL `acquireToken*` returning a result lacking `accessToken` or `expiresOn` (null/undefined or a Partial), passed into the provider. Happens on silent-acquire failures that resolve instead of reject, or malformed cached results.

Common situations: Wrong/missing scopes; invalid client credentials; MSAL token cache corruption; account not present for silent acquisition; misconfigured `getToken` callback.

Understand the failure class

Related errors


AI-assisted analysis of redis/node-redis@90fd0652bc (2026-08-11). Data as JSON: /api/errors/5a550ba95e753416. Report an issue: GitHub.

Appendix: source

Thrown at packages/entraid/lib/msal-identity-provider.ts:17

import {
  AuthenticationResult
} from '@azure/msal-node';
import { IdentityProvider, TokenResponse } from '@redis/client/dist/lib/authx';

export class MSALIdentityProvider implements IdentityProvider<AuthenticationResult> {
  private readonly getToken: () => Promise<AuthenticationResult>;

  constructor(getToken: () => Promise<AuthenticationResult>) {
    this.getToken = getToken;
  }

  async requestToken(): Promise<TokenResponse<AuthenticationResult>> {
    const result = await this.getToken();

    if (!result?.accessToken || !result?.expiresOn) {
      throw new Error('Invalid token response');
    }
    return {
      token: result,
      ttlMs: result.expiresOn.getTime() - Date.now()
    };
  }

}

View on GitHub (pinned to 90fd0652bc)