nextauthjs/next-auth · critical
TODO: Authorization server did not provide a token endpoint.
Error message
TODO: Authorization server did not provide a token endpoint.
What it means
During OAuth/OIDC discovery, Auth.js processes the issuer's well-known configuration with the openid-client library and requires a token_endpoint to exchange the authorization code. If the discovery document lacks one, a TypeError with this (work-in-progress) message is thrown. It almost always means the provider's discovery metadata is incomplete or the issuer URL is wrong.
Source
Thrown at packages/core/src/lib/actions/callback/oauth/callback.ts:72
let as: o.AuthorizationServer
const { token, userinfo } = provider
// Falls back to authjs.dev if the user only passed params
if (
(!token?.url || token.url.host === "authjs.dev") &&
(!userinfo?.url || userinfo.url.host === "authjs.dev")
) {
// We assume that issuer is always defined as this has been asserted earlier
const issuer = new URL(provider.issuer!)
const discoveryResponse = await o.discoveryRequest(issuer, {
[o.allowInsecureRequests]: true,
[o.customFetch]: provider[customFetch],
})
as = await o.processDiscoveryResponse(issuer, discoveryResponse)
if (!as.token_endpoint)
throw new TypeError(
"TODO: Authorization server did not provide a token endpoint."
)
if (!as.userinfo_endpoint)
throw new TypeError(
"TODO: Authorization server did not provide a userinfo endpoint."
)
} else {
as = {
issuer: provider.issuer ?? "https://authjs.dev", // TODO: review fallback issuer
token_endpoint: token?.url.toString(),
userinfo_endpoint: userinfo?.url.toString(),
}
}
const client: o.Client = {
client_id: provider.clientId,
...provider.client,View on GitHub (pinned to a1a16a5a77)
Solutions
- Verify {issuer}/.well-known/openid-configuration in a browser/curl and confirm it contains token_endpoint
- Correct the provider `issuer` URL (trailing-slash, path prefix, environment hostname) so real metadata is fetched
- If the server truly has no token endpoint, configure wellKnown/token_endpoint explicitly or provide authorization/token endpoints manually in the provider config
- Use a well-known provider preset (e.g. from @auth/core/providers) that declares endpoints directly, skipping discovery
Example fix
// before
providers: [Github({ issuer: "https://auth.example.com" })] // partial discovery
// after
providers: [{
id: "github",
type: "oauth",
authorization: { url: "https://github.com/login/oauth/authorize" },
token: "https://github.com/login/oauth/access_token",
userinfo: "https://api.github.com/user",
...
}] Defensive patterns
Strategy: validation
Validate before calling
const issuer = "https://sso.acme.com"
const doc = await fetch(`${issuer}/.well-known/openid-configuration`).then(r => r.json())
if (!doc.token_endpoint) throw new Error(`Issuer ${issuer} has no token_endpoint`) Type guard
function hasTokenEndpoint(as: unknown): as is { token_endpoint: string } {
return typeof as === "object" && as !== null && typeof (as as any).token_endpoint === "string"
} Try / catch
try {
await signIn(providerId)
} catch (e) {
if ((e as Error).message.includes("did not provide a token endpoint")) {
// verify issuer URL or declare token endpoint manually in provider config
}
} Prevention
- Curl the well-known discovery URL after configuring any new issuer
- Provide token/authorization/userinfo endpoints explicitly for OAuth2-only servers
- Avoid trailing slashes and path mistakes in issuer URLs
- Pin a provider preset instead of raw issuer discovery when metadata is known-bad
When it happens
Trigger: Provider configured with an `issuer` whose /.well-known/openid-configuration (or oauth-authorization-server) response does not include token_endpoint — e.g. an OAuth 2.0 (non-OIDC) server, a misconfigured issuer URL that hits a gateway returning partial metadata, or a stub/mock server.
Common situations: Pointing issuer at a wrong base URL so discovery returns an HTML page or minimal config; using providers that only implement authorization + userinfo without a token endpoint; wellKnown omitted while issuer serves partial metadata; corporate proxies returning a cached/trimmed document.
Related errors
- Discovery request responded with an invalid issuer. expected
- Authorization server did not provide an authorization endpoi
- TODO: Authorization server did not provide a userinfo endpoi
- unsupported client authentication method
- No userinfo endpoint configured
AI-assisted analysis of nextauthjs/next-auth@a1a16a5a77 (2026-08-28).
Data as JSON: /api/errors/cbbfc90599802f02.
Report an issue: GitHub.