elsa-workflows/elsa-core · error · ArgumentException

The issuer must be an absolute HTTPS URI without a query or…

Error message

The issuer must be an absolute HTTPS URI without a query or fragment.

What it means

A validation guard thrown by NormalizeIssuer in ExternalIdentityLinkManagementService: the supplied issuer string is not an absolute URI, is not HTTPS, or carries a query string or fragment. Only a clean absolute HTTPS issuer URL can be normalized (trailing slash trimmed) for use as an external identity link key.

Solutions

  1. Pass the identity provider's base issuer URL exactly as published in its OIDC discovery metadata (no query or fragment).
  2. Ensure the scheme is https://, not http:// or a relative URL.
  3. Trim any client-side appended parameters before passing the issuer to the link management service.
Defensive patterns

Strategy: validation

When it happens

Trigger: Thrown at src/modules/Elsa.ExternalAuthentication/Services/ExternalIdentityLinkManagementService.cs:236 when the library encounters an invalid state.

Common situations: See trigger scenarios.


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

Appendix: source

Thrown at src/modules/Elsa.ExternalAuthentication/Services/ExternalIdentityLinkManagementService.cs:236

        await sender.SendAsync(
            new ExternalIdentityLinkReplaced(
                context,
                oldLink.Id,
                newLink?.Id,
                oldLink.UserId,
                targetUserId,
                oldLink.ConnectionKey,
                targetConnectionKey,
                conflictingLink?.Id,
                conflictingLink?.UserId,
                conflictingLink?.ConnectionKey),
            cancellationToken);
    }

    private static string NormalizeIssuer(string issuer)
    {
        if (!Uri.TryCreate(issuer?.Trim(), UriKind.Absolute, out var uri) || !string.Equals(uri.Scheme, Uri.UriSchemeHttps, StringComparison.OrdinalIgnoreCase) || !string.IsNullOrEmpty(uri.Query) || !string.IsNullOrEmpty(uri.Fragment))
            throw new ArgumentException("The issuer must be an absolute HTTPS URI without a query or fragment.", nameof(issuer));
        return uri.GetComponents(UriComponents.AbsoluteUri, UriFormat.UriEscaped).TrimEnd('/');
    }

    private static string NormalizeSubject(string subject)
    {
        var normalized = subject?.Trim();
        if (string.IsNullOrEmpty(normalized) || normalized.Length > 4096)
            throw new ArgumentException("The subject is required and must not exceed 4096 characters.", nameof(subject));
        return normalized;
    }

    private static void ValidateTargetTenant(string tenantId)
    {
        ArgumentNullException.ThrowIfNull(tenantId);
        if (string.Equals(tenantId, ConnectionScope.HostTenantId, StringComparison.Ordinal))
            throw new ArgumentException("External identity links require a resolved tenant.", nameof(tenantId));
    }
}

View on GitHub (pinned to fe9217bdfa)