nextauthjs/next-auth · error

Provider not supported

Error message

Provider not supported

What it means

handleLoginOrRegister only accepts account types 'email', 'oauth', 'oidc', and 'webauthn'. If the account object passed through the callback action has any other type value, it throws this Error at handle-login.ts:36. It guards the internal login/link flow from unsupported account kinds.

Source

Thrown at packages/core/src/lib/actions/callback/handle-login.ts:36

 *
 * It prevents insecure behaviour, such as linking OAuth accounts unless a user is
 * signed in and authenticated with an existing valid account.
 *
 * All verification (e.g. OAuth flows or email address verification flows) are
 * done prior to this handler being called to avoid additional complexity in this
 * handler.
 */
export async function handleLoginOrRegister(
  sessionToken: SessionToken,
  _profile: User | AdapterUser | { email: string },
  _account: AdapterAccount | Account | null,
  options: InternalOptions
) {
  // Input validation
  if (!_account?.providerAccountId || !_account.type)
    throw new Error("Missing or invalid provider account")
  if (!["email", "oauth", "oidc", "webauthn"].includes(_account.type))
    throw new Error("Provider not supported")

  const {
    adapter,
    jwt,
    events,
    session: { strategy: sessionStrategy, generateSessionToken },
  } = options

  // If no adapter is configured then we don't have a database and cannot
  // persist data; in this mode we just return a dummy session object.
  if (!adapter) {
    return { user: _profile as User, account: _account as Account }
  }

  const profile = _profile as AdapterUser
  let account = _account as AdapterAccount

  const {

View on GitHub (pinned to a1a16a5a77)

Solutions

  1. Set the account type to one of 'oauth', 'oidc', 'email', or 'webauthn' in your provider.
  2. Use the Credentials Provider's built-in authorize() flow instead of the callback action for credentials logins.
  3. Align @auth/core and provider package versions so the type enum matches.

Example fix

// before
account = { providerAccountId: id, type: 'custom', provider: 'x' }
// after
account = { providerAccountId: id, type: 'oauth', provider: 'x' }
Defensive patterns

Strategy: type-guard

Validate before calling

const VALID_TYPES = ['email', 'oauth', 'oidc', 'webauthn']
if (!VALID_TYPES.includes(account.type)) throw new Error(`Account type '${account.type}' not supported by callback flow`)

Type guard

function isSupportedAccountType(t: string): t is 'email' | 'oauth' | 'oidc' | 'webauthn' {
  return ['email', 'oauth', 'oidc', 'webauthn'].includes(t)
}

Try / catch

try {
  await handleCallback(...)
} catch (e) {
  if ((e as Error).message === 'Provider not supported') {
    // route credentials logins through authorize(), not the callback action
  }
}

Prevention

When it happens

Trigger: An account object with type 'credentials' or an arbitrary custom string reaching the callback action; a custom provider setting an invalid account type; manually invoking the internal callback handler with a hand-built account.

Common situations: Trying to route Credentials Provider logins through the OAuth callback path; custom provider authors setting type to something like 'custom' expecting it to work; version mismatches between @auth/core and provider adapters that changed type constants.

Related errors


AI-assisted analysis of nextauthjs/next-auth@a1a16a5a77 (2026-08-28). Data as JSON: /api/errors/f4b93034c6b29c3f. Report an issue: GitHub.