nextauthjs/next-auth · error
unsupported client authentication method
Error message
unsupported client authentication method
What it means
Auth.js selects the client authentication method for the token endpoint based on token_endpoint_auth_method; only client_secret_basic, client_secret_post, and none are supported. Any other value reaches the switch's default branch and throws Error('unsupported client authentication method'). The valid values mirror openid-client's supported authentication methods.
Source
Thrown at packages/core/src/lib/actions/callback/oauth/callback.ts:125
case "client_secret_post":
clientAuth = o.ClientSecretPost(provider.clientSecret!)
break
case "client_secret_jwt":
clientAuth = o.ClientSecretJwt(provider.clientSecret!)
break
case "private_key_jwt":
clientAuth = o.PrivateKeyJwt(provider.token!.clientPrivateKey!, {
// TODO: review in the next breaking change
[o.modifyAssertion](_header, payload) {
payload.aud = [as.issuer, as.token_endpoint!]
},
})
break
case "none":
clientAuth = o.None()
break
default:
throw new Error("unsupported client authentication method")
}
const resCookies: Cookie[] = []
const state = await checks.state.use(cookies, resCookies, options)
let codeGrantParams: URLSearchParams
try {
codeGrantParams = o.validateAuthResponse(
as,
client,
new URLSearchParams(params),
provider.checks.includes("state") ? state : o.skipStateCheck
)
} catch (err) {
if (err instanceof o.AuthorizationResponseError) {
const cause = {
providerId: provider.id,View on GitHub (pinned to a1a16a5a77)
Solutions
- Set the provider's token_endpoint_auth_method to "client_secret_basic", "client_secret_post", or "none" (whichever the IdP accepts)
- Check the IdP's discovery document for which methods its token endpoint supports and pick a supported one
- If the IdP only supports private_key_jwt/mTLS, use a middleware or a different client that implements it, or ask the IdP to enable client_secret_* auth
- Fix casing/typos in custom provider definitions
Example fix
// before
const provider = {
id: "acme", type: "oidc", issuer: "https://sso.acme.com",
token_endpoint_auth_method: "private_key_jwt", clientId, clientSecret
}
// after
const provider = {
id: "acme", type: "oidc", issuer: "https://sso.acme.com",
token_endpoint_auth_method: "client_secret_post", clientId, clientSecret
} Defensive patterns
Strategy: validation
Validate before calling
const allowed = ["client_secret_basic", "client_secret_post", "none"]
if (provider.token_endpoint_auth_method &&
!allowed.includes(provider.token_endpoint_auth_method)) {
throw new Error(`Unsupported auth method: ${provider.token_endpoint_auth_method}`)
} Type guard
function isSupportedAuthMethod(m: string): m is "client_secret_basic" | "client_secret_post" | "none" {
return ["client_secret_basic","client_secret_post","none"].includes(m)
} Try / catch
try {
await signIn(providerId)
} catch (e) {
if ((e as Error).message === "unsupported client authentication method") {
// set token_endpoint_auth_method to a supported value
}
} Prevention
- Only use client_secret_basic, client_secret_post, or none in provider configs
- Read the IdP's discovery doc for supported token auth methods
- Watch out for casing/typos in hand-written provider objects
- For IdPs requiring private_key_jwt/mTLS, use a different integration layer
When it happens
Trigger: A provider config (or discovery document) declares token_endpoint_auth_method with a value such as private_key_jwt, tls_client_auth, or an arbitrary string that Auth.js does not implement; a typo like "client_secret_Post" in a custom provider.
Common situations: Providers requiring advanced auth (mTLS, private_key_jwt — e.g. some enterprise/healthcare IdPs) being wired into Auth.js which lacks support; copy-pasting token_endpoint_auth_method from the IdP's docs verbatim; hand-written provider objects with invalid enum values.
Understand the failure class
- Authentication and authorization failures — expired tokens, bad credentials, and missing scopes.
Related errors
- TODO: Authorization server did not provide a token endpoint.
- No userinfo endpoint configured
- State data was provided but the provider is not configured t
- Discovery request responded with an invalid issuer. expected
- Authorization server did not provide an authorization endpoi
AI-assisted analysis of nextauthjs/next-auth@a1a16a5a77 (2026-08-28).
Data as JSON: /api/errors/7574bb6fbc36fff9.
Report an issue: GitHub.