{"record":{"id":"ac0d7290c131f16c","repo":"elsa-workflows/elsa-core","slug":"the-identity-provider-metadata-could-not-be-resolved","errorCode":null,"errorMessage":"The identity provider metadata could not be resolved.","messagePattern":"The identity provider metadata could not be resolved\\.","errorType":"exception","errorClass":"OpenIdConnectAuthenticationException","httpStatus":null,"severity":"error","filePath":"src/modules/Elsa.ExternalAuthentication.OpenIdConnect/Services/OpenIdConnectExternalAuthenticationAdapter.cs","lineNumber":144,"sourceCode":"    }\n\n    private async Task<OpenIdConnectConnectionSettings> GetSettingsAsync(JsonElement settings, CancellationToken cancellationToken)\n    {\n        if (!settingsParser.TryParse(settings, out var parsed, out _))\n            throw new OpenIdConnectAuthenticationException(\"The OpenID Connect connection configuration is invalid.\");\n        await Task.CompletedTask;\n        return parsed!;\n    }\n\n    private async Task<ProviderMetadata> ResolveMetadataAsync(OpenIdConnectConnectionSettings settings, CancellationToken cancellationToken)\n    {\n        if (settings.TrustMode == OpenIdConnectTrustMode.Manual)\n            return new(settings.Issuer!, settings.AuthorizationEndpoint!, settings.TokenEndpoint!, settings.UserInfoEndpoint, settings.EndSessionEndpoint, settings.JwksUri, settings.SigningKeys);\n\n        var address = settings.DiscoveryUrl ?? throw new OpenIdConnectAuthenticationException(\"The OpenID Connect discovery URL is required.\");\n        var response = await providerHttpClient.GetAsync(address, ProviderResponseKind.Discovery, cancellationToken);\n        if (!response.IsSuccessStatusCode)\n            throw new OpenIdConnectAuthenticationException(\"The identity provider metadata could not be resolved.\");\n        using var document = ParseProviderJson(response.Body, \"The identity provider metadata could not be resolved.\");\n        var root = document.RootElement;\n        var issuer = GetRequiredHttpsUri(root, \"issuer\").AbsoluteUri.TrimEnd('/');\n        var authorizationEndpoint = GetRequiredHttpsUri(root, \"authorization_endpoint\");\n        var tokenEndpoint = GetRequiredHttpsUri(root, \"token_endpoint\");\n        return new(issuer, authorizationEndpoint, tokenEndpoint, GetOptionalHttpsUri(root, \"userinfo_endpoint\"), GetOptionalHttpsUri(root, \"end_session_endpoint\"), GetOptionalHttpsUri(root, \"jwks_uri\"), default);\n    }\n\n    private async Task<string> ExchangeCodeAsync(OpenIdConnectConnectionSettings settings, ProviderMetadata metadata, ExternalCallbackContext context, string? verifier, CancellationToken cancellationToken)\n    {\n        if (!TryGetParameter(context.Parameters, \"code\", out var code))\n            throw new OpenIdConnectAuthenticationException(\"The identity provider callback did not contain an authorization code.\");\n\n        var values = new Dictionary<string, string>\n        {\n            [\"grant_type\"] = \"authorization_code\",\n            [\"code\"] = code,\n            [\"redirect_uri\"] = GetCallbackUri(context.Connection, context.Transaction.Purpose).AbsoluteUri","sourceCodeStart":126,"sourceCodeEnd":162,"githubUrl":"https://github.com/elsa-workflows/elsa-core/blob/fe9217bdfa0e27f0e09e45006eb6898f616e513d/src/modules/Elsa.ExternalAuthentication.OpenIdConnect/Services/OpenIdConnectExternalAuthenticationAdapter.cs#L126-L162","documentation":"In discovery mode, ResolveMetadataAsync requests the discovery URL through providerHttpClient and checks IsSuccessStatusCode. A non-success response (or unparseable body passed to ParseProviderJson with the same message) yields this exception, meaning the provider's OpenID Connect metadata could not be retrieved.","triggerScenarios":"ResolveMetadataAsync where providerHttpClient.GetAsync on settings.DiscoveryUrl returns a non-success status, or ParseProviderJson fails on the response body.","commonSituations":"Wrong discovery URL or typo in the authority; the provider is unreachable (firewall, DNS, private network); discovery endpoint disabled; TLS certificate issues; server returning 500 or 404.","solutions":["Verify the discovery URL is correct by opening it in a browser or curl — it must return the openid-configuration JSON.","Check network reachability from the Elsa host (DNS, proxy, firewall, egress rules) to the identity provider.","Confirm TLS trust: a self-signed or private-CA certificate on the provider will make the request fail; install the CA chain.","Fall back to TrustMode.Manual with explicit endpoints if discovery is unavailable at the provider."],"exampleFix":"// before\n\"discoveryUrl\": \"https://idp.example.com/.well-known/openid-configuration\" // host unreachable\n// after (manual mode fallback)\n{ \"trustMode\": \"Manual\", \"issuer\": \"https://idp.example.com\", \"authorizationEndpoint\": \"https://idp.example.com/authorize\", \"tokenEndpoint\": \"https://idp.example.com/token\" }","handlingStrategy":"retry","validationCode":"using var http = new HttpClient(); var probe = await http.GetAsync(discoveryUrl); if (!probe.IsSuccessStatusCode) logger.LogError(\"Discovery endpoint returned {Status}\", probe.StatusCode);","typeGuard":null,"tryCatchPattern":"try { await adapter.TestAsync(testContext); } catch (OpenIdConnectAuthenticationException ex) when (ex.Message.Contains(\"metadata could not be resolved\")) { logger.LogError(ex, \"Discovery fetch failed for {Url}\", discoveryUrl); throw; }","preventionTips":["Pre-flight check the discovery URL from the Elsa host before saving the connection.","Configure proxies/firewall egress to the identity provider authority.","Install private CA certificates in the host trust store for TLS.","Use Manual trust mode with explicit endpoints when discovery is unavailable."],"tags":["openid-connect","network","discovery","http"],"backgroundTag":"http-error-response","analyzedSha":"fe9217bdfa0e27f0e09e45006eb6898f616e513d","analyzedAt":"2026-09-13T20:32:34.702Z","contentChangedAt":"2026-09-13T20:32:34.702Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}