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

  1. Verify {issuer}/.well-known/openid-configuration in a browser/curl and confirm it contains token_endpoint
  2. Correct the provider `issuer` URL (trailing-slash, path prefix, environment hostname) so real metadata is fetched
  3. If the server truly has no token endpoint, configure wellKnown/token_endpoint explicitly or provide authorization/token endpoints manually in the provider config
  4. 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

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


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