quarkusio/quarkus · error · io.quarkus.runtime.configuration.ConfigurationException
Dynamic tenant ID cannot be same as the default tenant ID: %
Error message
Dynamic tenant ID cannot be same as the default tenant ID: %s
What it means
Quarkus OIDC reserves the tenant ID "default" for the built-in default tenant. When an application creates a dynamic tenant (e.g. via OidcTenantConfigResolver or programmatically), its ID must differ from the default tenant ID, otherwise tenant lookup would be ambiguous. TenantContextFactory.createDynamic rejects such a configuration at startup by throwing this ConfigurationException.
Source
Thrown at extensions/oidc/runtime/src/main/java/io/quarkus/oidc/runtime/TenantContextFactory.java:88
var defaultTenantInitializer = createStaticTenantContextCreator(defaultTenant, foundNamedStaticTenants,
defaultTenantId);
return createStaticTenantContext(defaultTenant, foundNamedStaticTenants, defaultTenantId, defaultTenantInitializer);
}
Map<String, TenantConfigContext> createStaticTenantConfigs(Map<String, OidcTenantConfig> staticTenants,
OidcTenantConfig defaultTenant) {
final String defaultTenantId = defaultTenant.tenantId().get();
Map<String, TenantConfigContext> staticTenantsConfig = new HashMap<>();
for (var tenant : staticTenants.entrySet()) {
createStaticTenantConfig(defaultTenantId, tenant.getKey(), tenant.getValue(), staticTenantsConfig);
}
return Map.copyOf(staticTenantsConfig);
}
Uni<TenantConfigContext> createDynamic(OidcTenantConfig oidcConfig) {
var tenantId = oidcConfig.tenantId().orElseThrow();
if (OidcUtils.DEFAULT_TENANT_ID.equals(tenantId)) {
throw new ConfigurationException("Dynamic tenant ID cannot be same as the default tenant ID: " + tenantId);
}
return createTenantContext(oidcConfig, false, tenantId)
.onFailure().transform(new Function<Throwable, Throwable>() {
@Override
public Throwable apply(Throwable t) {
return logTenantConfigContextFailure(t, tenantId);
}
});
}
private void createStaticTenantConfig(String defaultTenantId, String tenantKey, OidcTenantConfig namedTenantConfig,
Map<String, TenantConfigContext> staticTenantsConfig) {
OidcCommonUtils.verifyConfigurationId(defaultTenantId, tenantKey, namedTenantConfig.tenantId());
var staticTenantInitializer = createStaticTenantContextCreator(namedTenantConfig, false, tenantKey);
staticTenantsConfig.put(tenantKey,
createStaticTenantContext(namedTenantConfig, false, tenantKey, staticTenantInitializer));
}
View on GitHub (pinned to e1c734241f)
Solutions
- Change the dynamic tenant's tenant-id to any value other than "default" (e.g. set .tenantId("acme")).
- If the tenant really is the default one, move its settings into quarkus.oidc.* properties (the static default tenant) instead of a dynamic config.
- If the ID comes from user input (path/header), validate or reject the value "default" before building the OidcTenantConfig.
Example fix
// before
OidcTenantConfig config = OidcTenantConfig.fromName("default"); // passed to resolver
// after
OidcTenantConfig config = OidcTenantConfig.fromName("acme"); Defensive patterns
Strategy: validation
Validate before calling
String tenantId = config.tenantId().orElseThrow();
if ("default".equals(tenantId)) {
throw new IllegalArgumentException("Dynamic tenant id must differ from 'default'");
} Prevention
- Never hardcode "default" as a tenant-id in resolvers or programmatic tenant creation.
- Sanitize tenant IDs derived from request data to reject reserved values.
- Keep dynamic tenant naming in one constants/utility class.
When it happens
Trigger: Calling TenantContextFactory.createDynamic(oidcConfig) where oidcConfig.tenantId() resolves to OidcUtils.DEFAULT_TENANT_ID ("default") — e.g. a TenantConfigResolver returning a config with tenant-id "default", or programmatic tenant registration that reuses the default ID.
Common situations: Writing an OidcTenantConfigResolver that copies tenant-id from a request path/header which happens to be "default"; migrating a static named tenant into a dynamic resolver but forgetting to rename it; copy-pasting tenant config builder code and leaving tenant-id("default") in place.
Related errors
- Both public key and certificate chain verification modes are
- '%s' property must be configured
- UserInfo is not required but UserInfo is expected to be the
- UserInfo is not required but '%s' is enabled
- UserInfo is not required for OIDC tenant '%s' but it will be
AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05).
Data as JSON: /api/errors/cd3cd8f1863cbb83.
Report an issue: GitHub.