{"record":{"id":"043ae2c4392af2d8","repo":"immich-app/immich","slug":"error-in-oauth-discovery-error","errorCode":null,"errorMessage":"Error in OAuth discovery: ${error}","messagePattern":"Error in OAuth discovery: (.+?)","errorType":"exception","errorClass":"InternalServerErrorException","httpStatus":500,"severity":"error","filePath":"server/src/repositories/oauth.repository.ts","lineNumber":223,"sourceCode":"    try {\n      return await discovery(\n        new URL(issuerUrl),\n        clientId,\n        {\n          client_secret: clientSecret,\n          response_types: ['code'],\n          userinfo_signed_response_alg: profileSigningAlgorithm === 'none' ? undefined : profileSigningAlgorithm,\n          id_token_signed_response_alg: signingAlgorithm,\n        },\n        this.getTokenAuthMethod(tokenEndpointAuthMethod, clientSecret),\n        {\n          execute: allowInsecureRequests ? [allowInsecureRequestsExecute] : [],\n          timeout,\n        },\n      );\n    } catch (error: any | AggregateError) {\n      this.logger.error('Error in OAuth discovery', error);\n      throw new InternalServerErrorException(`Error in OAuth discovery: ${error}`, { cause: error });\n    }\n  }\n\n  private getTokenAuthMethod(tokenEndpointAuthMethod: OAuthTokenEndpointAuthMethod, clientSecret?: string) {\n    if (!clientSecret) {\n      return None();\n    }\n\n    switch (tokenEndpointAuthMethod) {\n      case OAuthTokenEndpointAuthMethod.ClientSecretPost: {\n        return ClientSecretPost(clientSecret);\n      }\n\n      case OAuthTokenEndpointAuthMethod.ClientSecretBasic: {\n        return ClientSecretBasic(clientSecret);\n      }\n\n      default: {","sourceCodeStart":205,"sourceCodeEnd":241,"githubUrl":"https://github.com/immich-app/immich/blob/e55ac299a4ec7cb372e35dbf2c6c05ee9ce77f6c/server/src/repositories/oauth.repository.ts#L205-L241","documentation":"getClient performs OIDC discovery (fetching /.well-known/openid-configuration via openid-client) and wraps failures in an InternalServerErrorException with this message. Any discovery failure — DNS failure, TLS error, timeout, non-OIDC response, or AggregateError across multiple resolved addresses — results in this 500 error.","triggerScenarios":"First client request triggers discovery against issuerUrl; the well-known document is unreachable, times out (per configured timeout), returns invalid metadata, or all candidate addresses fail (AggregateError, e.g. IPv6 then IPv4 refused).","commonSituations":"Issuer URL typo or internal-only provider unreachable from the server; firewall blocks egress; provider briefly down; allowInsecureRequests not enabled while testing against http:// local IdP; DNS resolving to unreachable IPv6 addresses.","solutions":["Verify the issuerUrl is reachable from the server: curl <issuerUrl>/.well-known/openid-configuration","Check DNS/firewall/egress rules and whether IPv6 resolution is failing (AggregateError)","Set allowInsecureRequests when the issuer is http:// (local/dev only)","Increase the discovery timeout or check provider health/status page"],"exampleFix":"// before\ndiscovery(server, issuerUrl) // fails on http://localhost provider\n// after\ndiscovery(server, issuerUrl, { execute: [allowInsecureRequests] }) // dev-only insecure discovery","handlingStrategy":"retry","validationCode":"const wellKnown = `${issuerUrl.replace(/\\/$/, '')}/.well-known/openid-configuration`;\nconst res = await fetch(wellKnown).catch(() => null);\nif (!res?.ok) throw new Error(`Discovery endpoint unreachable: ${wellKnown}`);","typeGuard":null,"tryCatchPattern":"try {\n  await oauthRepo.getClient({ issuerUrl /* ... */ });\n} catch (e) {\n  if (String(e.message).startsWith('Error in OAuth discovery')) {\n    logger.error('Discovery failed — check issuer URL reachability/egress', { cause: (e as any).cause });\n    throw new ServiceUnavailableError('Identity provider unreachable');\n  }\n  throw e;\n}\n// plus: retry with exponential backoff for transient network failures","preventionTips":["Run a readiness probe that hits the discovery endpoint before serving traffic","Enable allowInsecureRequests only for http:// dev issuers","Check IPv6/IPv4 resolution (AggregateError often means all A/AAAA candidates failed)","Increase the discovery timeout for slow providers and cache clients after first fetch"],"tags":["oauth","oidc","discovery","network"],"backgroundTag":"http-request-failed","analyzedSha":"e55ac299a4ec7cb372e35dbf2c6c05ee9ce77f6c","analyzedAt":"2026-09-15T07:20:19.675Z","contentChangedAt":"2026-09-15T07:20:19.675Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}