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
- Open the connection settings JSON and validate it against the expected OpenIdConnectConnectionSettings fields (issuer, discoveryUrl or manual endpoints, clientId, etc.).
- For TrustMode.Manual, ensure Issuer, AuthorizationEndpoint and TokenEndpoint are all populated since discovery will be skipped.
- 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
- Validate connection settings JSON against the expected schema before saving.
- For Manual trust mode, always fill issuer, authorizationEndpoint, tokenEndpoint and clientId.
- Use a JSON linter to catch syntax errors in stored settings.
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
- The OpenID Connect discovery URL is required.
- The provider client secret is unavailable.
- The deployment callback base URI is not configured.
- The identity provider did not provide signing keys.
- OpenID Connect settings must be an object.
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)