{"record":{"id":"d831072084da79da","repo":"nextauthjs/next-auth","slug":"authorization-server-did-not-provide-an-authorizat","errorCode":null,"errorMessage":"Authorization server did not provide an authorization endpoint.","messagePattern":"Authorization server did not provide an authorization endpoint\\.","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/core/src/lib/actions/signin/authorization-url.ts","lineNumber":44,"sourceCode":"\n    const issuer = new URL(provider.issuer!)\n    const discoveryResponse = await o.discoveryRequest(issuer, {\n      [o.customFetch]: provider[customFetch],\n      // TODO: move away from allowing insecure HTTP requests\n      [o.allowInsecureRequests]: true,\n    })\n    const as = await o\n      .processDiscoveryResponse(issuer, discoveryResponse)\n      .catch((error) => {\n        if (!(error instanceof TypeError) || error.message !== \"Invalid URL\")\n          throw error\n        throw new TypeError(\n          `Discovery request responded with an invalid issuer. expected: ${issuer}`\n        )\n      })\n\n    if (!as.authorization_endpoint) {\n      throw new TypeError(\n        \"Authorization server did not provide an authorization endpoint.\"\n      )\n    }\n\n    url = new URL(as.authorization_endpoint)\n  }\n\n  const authParams = url.searchParams\n\n  let redirect_uri: string = provider.callbackUrl\n  let data: string | undefined\n  if (!options.isOnRedirectProxy && provider.redirectProxyUrl) {\n    redirect_uri = provider.redirectProxyUrl\n    data = provider.callbackUrl\n    logger.debug(\"using redirect proxy\", { redirect_uri, data })\n  }\n\n  const params = Object.assign(","sourceCodeStart":26,"sourceCodeEnd":62,"githubUrl":"https://github.com/nextauthjs/next-auth/blob/a1a16a5a7780488c7449feece410033f445d0b31/packages/core/src/lib/actions/signin/authorization-url.ts#L26-L62","documentation":"After successful OIDC discovery, Auth.js requires the provider metadata to include an authorization_endpoint. If the discovery document decodes successfully but lacks that field, this TypeError is thrown because the library cannot build the sign-in redirect URL.","triggerScenarios":"Provider's /.well-known/openid-configuration returns metadata without authorization_endpoint — typical of OAuth2-only servers (no OIDC), partially implemented providers, or misconfigured discovery endpoints that return minimal/empty metadata.","commonSituations":"Using issuer-based discovery against a plain OAuth2 provider (GitHub, custom APIs) that has no authorization_endpoint in metadata; provider misconfiguration returning an error JSON with 200 status; self-hosted Keycloak/Hydra exposing partial document; forgetting to set authorization endpoint manually for non-OIDC providers.","solutions":["For OAuth2-only providers, remove issuer/wellKnown and configure the endpoints explicitly: authorization: { url: 'https://provider.com/oauth/authorize' }, token: '...', userinfo: '...'","Inspect the discovery document output and confirm authorization_endpoint is present; fix the provider's discovery configuration if it is missing","If the document is behind a rewrite/proxy serving the wrong file, point issuer at the correct well-known location","Upgrade Auth.js if the provider advertises authorization_endpoint only in a newer metadata revision, or hardcode the endpoint as a workaround"],"exampleFix":"// before\nconst provider = { id: 'custom', issuer: 'https://api.example.com' }; // OAuth2-only, no discovery\n// after\nconst provider = {\n  id: 'custom',\n  authorization: { url: 'https://api.example.com/oauth/authorize' },\n  token: 'https://api.example.com/oauth/token',\n  userinfo: 'https://api.example.com/oauth/userinfo',\n};","handlingStrategy":"validation","validationCode":"const doc = await fetch(`${issuer}/.well-known/openid-configuration`).then(r => r.json());\nif (!doc.authorization_endpoint) throw new Error('Provider metadata lacks authorization_endpoint; configure endpoints manually');","typeGuard":"function hasAuthorizationEndpoint(doc: object): doc is { authorization_endpoint: string } {\n  return typeof (doc as any).authorization_endpoint === 'string';\n}","tryCatchPattern":"try {\n  await signIn(providerId);\n} catch (e) {\n  if (/did not provide an authorization endpoint/.test(String(e))) {\n    // fall back to explicitly configured authorization url for OAuth2-only providers\n  }\n}","preventionTips":["Only use issuer-based discovery for true OIDC providers; plain OAuth2 needs explicit endpoints","Inspect the discovery JSON with curl to confirm authorization_endpoint exists","Check provider realm/tenant path in the issuer URL is correct (Keycloak, Hydra)","Verify the discovery URL is not being served a partial or error document by a proxy"],"tags":["oauth","oidc","discovery","configuration"],"backgroundTag":"missing-authorization-endpoint","analyzedSha":"a1a16a5a7780488c7449feece410033f445d0b31","analyzedAt":"2026-08-28T21:52:38.200Z","schemaVersion":2},"datasetVersion":"2026-08-29T02:17:18.158Z"}