OrchardCMS/OrchardCore · error · SecurityTokenInvalidIssuerException
The token issuer is not valid.
Error message
The token issuer is not valid.
What it means
OpenIdConnect token validation is configured with a custom IssuerValidator that expects the token's iss claim to be an absolute URI whose host/path match an Orchard tenant (matched via _runningShellTable and compared to settings.Tenant). If the issuer is not a parseable absolute URI, or resolves to a different tenant, a SecurityTokenInvalidIssuerException is thrown and the token is rejected.
Solutions
- Align the token issuer URL (iss) with the tenant configured in the OpenIdConnect validation settings (Tenant field).
- Fix the issuing tenant's Authority/base URL so tokens carry the expected issuer URI.
- Check reverse-proxy forwarding (X-Forwarded-Host/Proto, UseForwardedHeaders) so issuer URLs match the public host.
- Update API clients to request tokens from the correct tenant endpoint.
- If you maintain this code, log the received issuer to ease diagnosis.
Defensive patterns
Strategy: try-catch
Validate before calling
// Validate the expected issuer before sending the token
var expectedIssuer = new Uri(settings.Authority);
if (!Uri.TryCreate(tokenIssuer, UriKind.Absolute, out var iss) ||
!string.Equals(iss.GetLeftPart(UriPartial.Authority), expectedIssuer.GetLeftPart(UriPartial.Authority), StringComparison.Ordinal))
throw new SecurityTokenInvalidIssuerException("Token issuer does not match the configured tenant."); Try / catch
try { await ValidateTokenAsync(token); }
catch (SecurityTokenInvalidIssuerException ex)
{ /* log ex.Message and the token iss claim; compare with the tenant's Authority URL */ } Prevention
- Keep the Authority/base URL of the issuing tenant identical to the issuer expected by the validating tenant.
- Configure forwarded headers so issuer URIs match public endpoints behind proxies.
- Regenerate client credentials after domain or tenant renames.
- Log the received iss claim (safely) during validation failures to speed diagnosis.
When it happens
Trigger: Presenting an OIDC/JWT token whose issuer URL does not exactly match the tenant configured in the OpenId validation settings — e.g. issuer with a different hostname, port, or path segment; malformed iss claim; tokens minted by another tenant.
Common situations: Misconfigured Authority/issuer in the token-issuing tenant; behind a reverse proxy where the public URL differs from the configured one; API clients hardcoding an issuer URL that predates a domain change; multi-tenant setups where the token was issued by tenant A but validated for tenant B.
Related errors
- Unable to reload the tenant
- Unexpected shell state for
- The 'Default' tenant can't be removed.
- The tenant ' ' can't be removed as it is neither…
- Can't resolve a scope on tenant
AI-assisted analysis of OrchardCMS/OrchardCore@4306c0717f (2026-09-13).
Data as JSON: /api/errors/e023a1836b1bc63e.
Report an issue: GitHub.
Appendix: source
Thrown at src/OrchardCore.Modules/OrchardCore.OpenId/Configuration/OpenIdValidationConfiguration.cs:183
// to validate/introspect tokens meant to be used with another tenant.
options.Audiences.Add(OpenIdConstants.Prefixes.Tenant + _shellSettings.Name);
// Note: token entry validation must be enabled to be able to validate reference tokens.
options.EnableTokenEntryValidation = configuration.UseReferenceAccessTokens;
// If an authority was explicitly set in the OpenID server options,
// prefer it to the dynamic tenant comparison as it's more efficient.
if (configuration.Authority != null)
{
options.TokenValidationParameters.ValidIssuer = configuration.Authority.AbsoluteUri;
}
else
{
options.TokenValidationParameters.IssuerValidator = (issuer, token, parameters) =>
{
if (!Uri.TryCreate(issuer, UriKind.Absolute, out var uri))
{
throw new SecurityTokenInvalidIssuerException("The token issuer is not valid.");
}
var tenant = _runningShellTable.Match(HostString.FromUriComponent(uri), uri.AbsolutePath);
if (tenant == null || !string.Equals(tenant.Name, settings.Tenant, StringComparison.Ordinal))
{
throw new SecurityTokenInvalidIssuerException("The token issuer is not valid.");
}
return issuer;
};
}
}).GetAwaiter().GetResult();
}
public void Configure(OpenIddictValidationDataProtectionOptions options)
{
var settings = GetValidationSettingsAsync().GetAwaiter().GetResult();
if (settings == null)View on GitHub (pinned to 4306c0717f)