nextauthjs/next-auth · error · UnknownAction
Unsupported action
Error message
Unsupported action
What it means
The built-in signin page handler throws UnknownAction("Unsupported action") when signin() is called with a providerId argument. A specific provider signin must be handled by rendering the provider list page or redirecting directly, not through this page action.
Source
Thrown at packages/core/src/lib/pages/index.ts:90
value: "",
options: { ...options.cookies.csrfToken.options, maxAge: 0 },
})
return { status: 404, cookies }
},
providers(providers: InternalProvider[]) {
return {
headers: { "Content-Type": "application/json" },
body: providers.reduce<Record<string, PublicProvider>>(
(acc, { id, name, type, signinUrl, callbackUrl }) => {
acc[id] = { id, name, type, signinUrl, callbackUrl }
return acc
},
{}
),
}
},
signin(providerId?: string, error?: any) {
if (providerId) throw new UnknownAction("Unsupported action")
if (pages?.signIn) {
let signinUrl = `${pages.signIn}${
pages.signIn.includes("?") ? "&" : "?"
}${new URLSearchParams({ callbackUrl: params.callbackUrl ?? "/" })}`
if (error) signinUrl = `${signinUrl}&${new URLSearchParams({ error })}`
return { redirect: signinUrl, cookies }
}
// If we have a webauthn provider with conditional UI and
// a simpleWebAuthnBrowserScript is defined, we need to
// render the script in the page.
const webauthnProvider = providers?.find(
(p): p is InternalProvider<"webauthn"> =>
p.type === "webauthn" &&
p.enableConditionalUI &&
!!p.simpleWebAuthnBrowserVersion
)
View on GitHub (pinned to a1a16a5a77)
Solutions
- Link to /auth/signin (no provider id) on the sign-in page and trigger provider sign-in via the client signIn() helper
- Use /auth/signin only for the provider-list page; start provider flows with signIn(providerId) from the browser
- If you want direct provider redirects via URL, ensure pages.signIn is not intercepting that route
Example fix
// before
<a href="/auth/signin/github">Sign in with GitHub</a> <!-- on custom pages.signIn -->
// after
<button onClick={() => signIn("github")}>Sign in with GitHub</button> Defensive patterns
Strategy: try-catch
Validate before calling
const providerMatch = pathname.match(/^\/auth\/signin\/(.+)$/); if (providerMatch && customSignInPageEnabled) throw new Error("Provider-specific signin must use client signIn(), not the sign-in page"); Type guard
null
Try / catch
try { return await renderSignInPage(providerId) } catch (e) { if (String(e.message).includes("Unsupported action")) return Response.redirect("/auth/signin"); throw e; } Prevention
- Never link to /auth/signin/<providerId>; use the client signIn(providerId) helper
- Keep custom sign-in page links pointing at the provider-less signin URL
- Review custom pages config for route conflicts with provider signin
When it happens
Trigger: Requesting /auth/signin/<providerId> while the pages.signIn page is rendered (the signin page action receives a providerId), meaning the framework tried to route a provider-specific signin through the generic sign-in page handler.
Common situations: Custom page configuration where pages.signIn is set and a link points to /auth/signin/google instead of initiating signin via signIn('google') client-side; broken manual links on a custom sign-in page.
Related errors
- [updateSession] Failed to fetch updated session
- Object is nullish
- User not found
- Account not found
- Session not found
AI-assisted analysis of nextauthjs/next-auth@a1a16a5a77 (2026-08-28).
Data as JSON: /api/errors/c485f930542b18db.
Report an issue: GitHub.