elsa-workflows/elsa-core · error · OpenIdConnectAuthenticationException

The OpenID Connect connection configuration is invalid.

Error message

The OpenID Connect connection configuration is invalid.

What it means

GetSettingsAsync parses the connection's AdapterSettings JSON through a settings parser. If parsing fails (required fields missing or values malformed), the adapter throws this OpenIdConnectAuthenticationException instead of proceeding with partial settings, indicating the OpenID Connect connection configuration is invalid.

Solutions

  1. Open the connection settings JSON and validate it against the expected OpenIdConnectConnectionSettings fields (issuer, discoveryUrl or manual endpoints, clientId, etc.).
  2. For TrustMode.Manual, ensure Issuer, AuthorizationEndpoint and TokenEndpoint are all populated since discovery will be skipped.
  3. Paste the settings JSON into a JSON validator and check for syntax errors, wrong types (numbers vs strings), or trailing commas.

Example fix

// before (invalid: missing tokenEndpoint in manual mode)
{ "trustMode": "Manual", "issuer": "https://idp.example.com", "authorizationEndpoint": "https://idp.example.com/authorize" }
// after
{ "trustMode": "Manual", "issuer": "https://idp.example.com", "authorizationEndpoint": "https://idp.example.com/authorize", "tokenEndpoint": "https://idp.example.com/token", "clientId": "my-client" }
Defensive patterns

Strategy: validation

Validate before calling

try { JsonDocument.Parse(adapterSettingsJson); } catch (JsonException ex) { throw new InvalidOperationException("Connection settings JSON is malformed: " + ex.Message); }

Try / catch

try { await adapter.TestAsync(testContext); } catch (OpenIdConnectAuthenticationException ex) when (ex.Message.Contains("configuration is invalid")) { return Results.ValidationProblem(new Dictionary<string, string[]> { ["settings"] = ["OpenID Connect connection settings are invalid."] }); }

Prevention

When it happens

Trigger: Any flow (initiation, callback, TestAsync) that calls GetSettingsAsync on a connection whose AdapterSettings JSON does not pass the settings parser's validation.

Common situations: Typo in JSON keys of the connection settings; issuer/endpoints supplied with invalid URI values; required fields left out when TrustMode is Manual; JSON saved as an object with unexpected nesting.

Understand the failure class

Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.

Related errors


AI-assisted analysis of elsa-workflows/elsa-core@fe9217bdfa (2026-09-13). Data as JSON: /api/errors/42941b82b1a2afc6. Report an issue: GitHub.

Appendix: source

Thrown at src/modules/Elsa.ExternalAuthentication.OpenIdConnect/Services/OpenIdConnectExternalAuthenticationAdapter.cs:131

        return new(ConnectionObservationStatus.Succeeded, "reachable", "Provider metadata was resolved.", []);
    }

    public async ValueTask<ExternalLogoutRequest?> CreateLogoutRequestAsync(ExternalLogoutContext context, CancellationToken cancellationToken = default)
    {
        var settings = await GetSettingsAsync(context.Connection.Connection.AdapterSettings, cancellationToken);
        var metadata = await ResolveMetadataAsync(settings, cancellationToken);
        if (metadata.EndSessionEndpoint is null)
            return null;
        var query = new Dictionary<string, string> { ["post_logout_redirect_uri"] = GetLogoutCallbackUri(context.Connection).AbsoluteUri, ["state"] = context.CorrelationState };
        if (context.UpstreamLogoutHint is not null)
            query["id_token_hint"] = context.UpstreamLogoutHint.Reveal();
        return new(WithQuery(metadata.EndSessionEndpoint, query), []);
    }

    private async Task<OpenIdConnectConnectionSettings> GetSettingsAsync(JsonElement settings, CancellationToken cancellationToken)
    {
        if (!settingsParser.TryParse(settings, out var parsed, out _))
            throw new OpenIdConnectAuthenticationException("The OpenID Connect connection configuration is invalid.");
        await Task.CompletedTask;
        return parsed!;
    }

    private async Task<ProviderMetadata> ResolveMetadataAsync(OpenIdConnectConnectionSettings settings, CancellationToken cancellationToken)
    {
        if (settings.TrustMode == OpenIdConnectTrustMode.Manual)
            return new(settings.Issuer!, settings.AuthorizationEndpoint!, settings.TokenEndpoint!, settings.UserInfoEndpoint, settings.EndSessionEndpoint, settings.JwksUri, settings.SigningKeys);

        var address = settings.DiscoveryUrl ?? throw new OpenIdConnectAuthenticationException("The OpenID Connect discovery URL is required.");
        var response = await providerHttpClient.GetAsync(address, ProviderResponseKind.Discovery, cancellationToken);
        if (!response.IsSuccessStatusCode)
            throw new OpenIdConnectAuthenticationException("The identity provider metadata could not be resolved.");
        using var document = ParseProviderJson(response.Body, "The identity provider metadata could not be resolved.");
        var root = document.RootElement;
        var issuer = GetRequiredHttpsUri(root, "issuer").AbsoluteUri.TrimEnd('/');
        var authorizationEndpoint = GetRequiredHttpsUri(root, "authorization_endpoint");
        var tokenEndpoint = GetRequiredHttpsUri(root, "token_endpoint");

View on GitHub (pinned to fe9217bdfa)