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
- Set the account type to one of 'oauth', 'oidc', 'email', or 'webauthn' in your provider.
- Use the Credentials Provider's built-in authorize() flow instead of the callback action for credentials logins.
- 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
- Use the Credentials Provider's authorize() for username/password flows, never the callback action.
- Keep account.type values to the four documented constants.
- Pin @auth/core and provider packages to compatible versions.
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
- Missing or invalid provider account
- Callback route called without provider
- OAuth Provider returned an error
- OAuth Provider returned an error: ${responseJson.error}
- token_type is 'bearer'. Redundant workaround, please open an
AI-assisted analysis of nextauthjs/next-auth@a1a16a5a77 (2026-08-28).
Data as JSON: /api/errors/f4b93034c6b29c3f.
Report an issue: GitHub.