quarkusio/quarkus · error · OIDCException
OidcProviderClient can not be injected
Error message
OidcProviderClient can not be injected
What it means
produceProviderClient() resolves the OidcProviderClient from the SecurityIdentity's TENANT_ID_ATTRIBUTE (default tenant, static tenant, or dynamic tenant). If the attribute is missing or maps to no known tenant, the client is null and OIDCException 'OidcProviderClient can not be injected' is thrown.
Source
Thrown at extensions/oidc/runtime/src/main/java/io/quarkus/oidc/runtime/OidcConfigurationAndProviderProducer.java:51
@Produces
@RequestScoped
OidcProviderClient produceProviderClient() {
OidcProviderClient client = null;
String tenantId = OidcUtils.getAttribute(identity, OidcUtils.TENANT_ID_ATTRIBUTE);
if (tenantId != null) {
if (OidcUtils.DEFAULT_TENANT_ID.equals(tenantId)) {
return tenantConfig.getDefaultTenant().getOidcProviderClient();
}
TenantConfigContext context = tenantConfig.getStaticTenant(tenantId);
if (context == null) {
context = tenantConfig.getDynamicTenant(tenantId);
}
if (context != null) {
client = context.getOidcProviderClient();
}
}
if (client == null) {
throw new OIDCException("OidcProviderClient can not be injected");
}
return client;
}
}
View on GitHub (pinned to e1c734241f)
Solutions
- Only inject OidcProviderClient in endpoints secured by OIDC (enforce authentication, e.g. quarkus.http.auth.permission policies) so TENANT_ID_ATTRIBUTE is set.
- Look up the client explicitly via TenantConfigBean (getDefaultTenant()/getStaticTenant(tenantId)) instead of injecting the produced bean.
- Ensure tenant names in configuration match those recorded in existing sessions after refactors; restart users through login if tenant ids changed.
Example fix
// before
@Inject OidcProviderClient client; // null on anonymous endpoints
// after
@Inject TenantConfigBean tenantConfig;
OidcProviderClient client = tenantConfig.getStaticTenant("hr").getOidcProviderClient(); Defensive patterns
Strategy: type-guard
Validate before calling
String tenantId = OidcUtils.getAttribute(identity, OidcUtils.TENANT_ID_ATTRIBUTE);
if (tenantId == null || tenantConfig.getStaticTenant(tenantId) == null) {
// endpoint not secured by OIDC or tenant no longer exists - avoid injecting
} Type guard
boolean hasProviderClient(SecurityIdentity identity, TenantConfigBean cfg) {
String tenantId = OidcUtils.getAttribute(identity, OidcUtils.TENANT_ID_ATTRIBUTE);
if (tenantId == null) return false;
if (OidcUtils.DEFAULT_TENANT_ID.equals(tenantId)) return true;
return cfg.getStaticTenant(tenantId) != null || cfg.getDynamicTenant(tenantId) != null;
} Try / catch
try {
return client.introspect(token).await().indefinitely();
} catch (OIDCException e) {
if (e.getMessage().contains("OidcProviderClient")) {
// request has no OIDC identity; respond 401 instead of 500
}
throw e;
} Prevention
- Secure endpoints that inject OidcProviderClient with OIDC auth requirements
- Look up clients via TenantConfigBean rather than injecting the producer
- Keep tenant ids stable across config refactors, or invalidate stale sessions
- Handle anonymous traffic in separate beans without OIDC injections
When it happens
Trigger: Inject OidcProviderClient in a request where SecurityIdentity lacks a TENANT_ID_ATTRIBUTE (unauthenticated or non-OIDC identity), or the attribute references a tenant not registered in tenantConfig (tenant removed/renamed while a session references the old id).
Common situations: Injecting OidcProviderClient into endpoints that allow anonymous access or use another IdentityProvider; stale sessions for a tenant deleted from configuration; using dynamic tenants resolved lazily so no client is bound yet at injection time.
Related errors
- OidcConfigurationMetadata can not be injected
- Failed to find a matching OidcTenantConfig for tenant:
- %s type can not be used to represent JWT claims in @Singleto
- Multiple interface io.quarkus.oidc.TenantConfigResolver bean
- Multiple interface io.quarkus.oidc.runtime.TokenStateManager
AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05).
Data as JSON: /api/errors/187c59aa95fada57.
Report an issue: GitHub.