{"record":{"id":"c85ecded4a9dfb72","repo":"nexu-io/open-design","slug":"could-not-discover-oauth-metadata-for-issuer","errorCode":null,"errorMessage":"could not discover OAuth metadata for ${issuer}","messagePattern":"could not discover OAuth metadata for (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"apps/daemon/src/mcp-oauth.ts","lineNumber":553,"sourceCode":" * correct authorize URL, and (b) finish the flow when the callback hits.\n */\nexport async function beginAuth(\n  input: BeginAuthInput,\n): Promise<BeginAuthResult> {\n  const fetchImpl = input.fetchImpl ?? fetch;\n\n  // Step 1: ask the MCP server who its auth server is. If the server\n  // doesn't publish protected-resource metadata, fall back to assuming\n  // the resource origin IS the auth server — most \"stand-alone\" MCP\n  // providers (Higgsfield etc.) host both at the same host.\n  const prm = await discoverProtectedResource(input.serverUrl, fetchImpl);\n  const issuerHint = prm?.authorization_servers?.[0];\n  const issuer = issuerHint ?? new URL(input.serverUrl).origin;\n\n  // Step 2: discovery on the auth server.\n  const authServer = await discoverAuthServer(issuer, fetchImpl);\n  if (!authServer) {\n    throw new Error(`could not discover OAuth metadata for ${issuer}`);\n  }\n\n  // Step 3: ensure we have a registered client_id (DCR if missing).\n  const client = await getOrRegisterClient(\n    input.dataDir,\n    authServer,\n    input.redirectUri,\n    fetchImpl,\n  );\n\n  // Step 4: PKCE + state.\n  const codeVerifier = generateCodeVerifier();\n  const codeChallenge = deriveCodeChallenge(codeVerifier);\n  const state = generateState();\n\n  const scope =\n    input.scope ??\n    (Array.isArray(prm?.scopes_supported) && prm!.scopes_supported!.length > 0","sourceCodeStart":535,"sourceCodeEnd":571,"githubUrl":"https://github.com/nexu-io/open-design/blob/5be4028344c2eb4c667c5a97bda8f750c5597ef7/apps/daemon/src/mcp-oauth.ts#L535-L571","documentation":"beginAuth Step 2 calls discoverAuthServer(issuer) and throws if it returns null, meaning no valid OAuth Authorization Server metadata could be fetched or parsed at the issuer (the /.well-known/oauth-authorization-server or RFC8414 fallback). Step 1 may have derived the issuer from the resource origin when the server published no protected-resource metadata.","triggerScenarios":"The issuer is unreachable or is not an auth server; the well-known endpoint returns 404; the metadata JSON is malformed; the MCP server's origin is not its auth server and no authorization_servers hint was published.","commonSituations":"A provider hosts auth on a different host but did not publish protected-resource metadata; a typo in serverUrl; a corporate network blocks the well-known path.","solutions":["Confirm serverUrl is correct and the auth server is discoverable at its issuer.","Ensure the MCP server publishes protected-resource metadata pointing at the real auth server via authorization_servers.","Check network or proxy access to /.well-known/oauth-authorization-server."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"const issuer = new URL(serverUrl).origin;\nconst meta = await discoverAuthServer(issuer);\nif (!meta) {\n  throw new Error('no OAuth metadata reachable; verify serverUrl and protected-resource metadata');\n}","typeGuard":null,"tryCatchPattern":"try {\n  await beginAuth(input);\n} catch (e) {\n  if (/could not discover OAuth metadata/i.test(e.message)) {\n    // verify serverUrl; ensure protected-resource metadata advertises the auth server\n    surfaceToUser('Check the MCP server URL and its auth server discovery.');\n  }\n  throw e;\n}","preventionTips":["Validate serverUrl before starting the OAuth flow.","Confirm the provider publishes protected-resource metadata when auth lives on another host.","Ensure network access to /.well-known/oauth-authorization-server."],"tags":["oauth","discovery","network"],"backgroundTag":null,"analyzedSha":"5be4028344c2eb4c667c5a97bda8f750c5597ef7","analyzedAt":"2026-08-12T12:03:58.812Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}