quarkusio/quarkus · error · IllegalStateException
Back-channel logout path cannot contain a wildcard '*' chara
Error message
Back-channel logout path cannot contain a wildcard '*' character
What it means
BackChannelLogoutHandler builds a path matcher from each tenant's back-channel logout path. A wildcard '*' in such a path cannot be matched deterministically for logout callbacks, so an IllegalStateException is thrown while creating/updating the path matcher.
Source
Thrown at extensions/oidc/runtime/src/main/java/io/quarkus/oidc/runtime/BackChannelLogoutHandler.java:111
}
}
}
private Set<String> createOrUpdatePathMatcher() {
ImmutablePathMatcher.ImmutablePathMatcherBuilder<Handler<RoutingContext>> builder = null;
Map<String, OidcTenantConfig> pathCache = null;
Set<String> tenantIdCache = null;
for (TenantConfigContext configContext : resolver.getTenantConfigBean().getAllTenantConfigs()) {
if (configContext.ready() && configContext.oidcConfig().tenantEnabled()
&& configContext.oidcConfig().logout().backchannel().path().isPresent()) {
if (builder == null) {
builder = ImmutablePathMatcher.builder();
pathCache = new HashMap<>();
tenantIdCache = new HashSet<>();
}
String routePath = getTenantLogoutPath(configContext);
if (routePath.contains("*")) {
throw new IllegalStateException("Back-channel logout path cannot contain a wildcard '*' character");
}
OidcTenantConfig previousConfig = pathCache.put(routePath, configContext.oidcConfig());
tenantIdCache.add(configContext.oidcConfig().tenantId().get());
if (previousConfig == null) {
Handler<RoutingContext> routeHandler = new RouteHandler(configContext, resolver);
builder.addPath(routePath, routeHandler);
} else {
String previousTenantId = previousConfig.tenantId().get();
String currentTenantId = configContext.oidcConfig().tenantId().get();
// maybe invalid state, but technically it could happen that some produces a static tenant with
// a same id as a dynamic tenant
if (!previousTenantId.equals(currentTenantId)) {
String errorMessage = "OIDC tenants '%s' and '%s' share the same back-channel logout path '%s', which is not supported"
.formatted(previousTenantId, currentTenantId, routePath);
LOG.error(errorMessage);
throw new OIDCException(errorMessage);
}
}View on GitHub (pinned to e1c734241f)
Solutions
- Set the back-channel logout path to a literal path without '*', e.g. /back-channel-logout
- Configure wildcard matching at the HTTP level if needed, keeping the OIDC tenant path exact
- Give each tenant a distinct exact logout path
Example fix
// before quarkus.oidc.tenant-a.logout.backchannel-path=/logout/* // after quarkus.oidc.tenant-a.logout.backchannel-path=/logout/tenant-a
Defensive patterns
Strategy: validation
Validate before calling
String p = tenant.logout().backchannel().path().orElse("");
if (p.contains("*")) throw new IllegalArgumentException("back-channel logout path must not contain '*': " + p); Try / catch
try { handler.createPathMatcher(); } catch (IllegalStateException e) { if (e.getMessage().contains("wildcard")) { /* fix tenant logout path config */ } } Prevention
- Use literal, exact logout paths per tenant
- Do not reuse HTTP route wildcard syntax in OIDC config
- Validate tenant config in integration tests
When it happens
Trigger: Configuring a tenant's back-channel logout path (e.g. via OidcTenantConfig logout.backchannelPath or getTenantLogoutPath) with a '*' glob character, then building the handler via createPathMatcher or currentTenantIds.
Common situations: Reusing an HTTP route pattern (like /logout/*) as the back-channel logout path; copying wildcard path syntax from quarkus.http auth permission paths into OIDC tenant config.
Related errors
- OIDC tenants '%s' and '%s' share the same back-channel logou
- Annotation '%s' placed on '%s' specifies no 'acr' value
- The '%s' annotation is only supported when proactive authent
- %s OidcClient can not complete the %s grant request because
- %s OidcClient wants to use JWT bearer grant assertion but ha
AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05).
Data as JSON: /api/errors/af89aa39b66f317a.
Report an issue: GitHub.