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

  1. Change the dynamic tenant's tenant-id to any value other than "default" (e.g. set .tenantId("acme")).
  2. If the tenant really is the default one, move its settings into quarkus.oidc.* properties (the static default tenant) instead of a dynamic config.
  3. 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

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


AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05). Data as JSON: /api/errors/cd3cd8f1863cbb83. Report an issue: GitHub.