quarkusio/quarkus · error · IllegalStateException
Method 'TenantResolver.getDefaultTenantId()' returned a null
Error message
Method 'TenantResolver.getDefaultTenantId()' returned a null value. This violates the contract of the interface!
What it means
TenantResolver.getDefaultTenantId() must return a non-null tenant id; this is the interface contract. Quarkus throws IllegalStateException when it returns null while fetching the connection provider for a tenant connection in a multi-tenant persistence unit.
Source
Thrown at extensions/hibernate-orm/runtime/src/main/java/io/quarkus/hibernate/orm/runtime/tenant/HibernateMultiTenantConnectionProvider.java:58
InstanceHandle<TenantResolver> tenantResolver = tenantResolver(persistenceUnitName);
String tenantId;
// Activate RequestScope if the TenantResolver is @RequestScoped or @SessionScoped
ManagedContext requestContext = Arc.container().requestContext();
Class<? extends Annotation> tenantScope = tenantResolver.getBean().getScope();
boolean requiresRequestScope = (tenantScope == RequestScoped.class || tenantScope == SessionScoped.class);
boolean forceRequestActivation = (!requestContext.isActive() && requiresRequestScope);
try {
if (forceRequestActivation) {
requestContext.activate();
}
tenantId = tenantResolver.get().getDefaultTenantId();
} finally {
if (forceRequestActivation) {
requestContext.deactivate();
}
}
if (tenantId == null) {
throw new IllegalStateException("Method 'TenantResolver.getDefaultTenantId()' returned a null value. "
+ "This violates the contract of the interface!");
}
return selectConnectionProvider(tenantId);
}
@Override
protected ConnectionProvider selectConnectionProvider(final String tenantIdentifier) {
LOG.debugv("selectConnectionProvider(persistenceUnitName={0}, tenantIdentifier={1})", persistenceUnitName,
tenantIdentifier);
ConnectionProvider provider = providerMap.get(tenantIdentifier);
if (provider == null) {
final ConnectionProvider connectionProvider = resolveConnectionProvider(persistenceUnitName, tenantIdentifier);
providerMap.put(tenantIdentifier, connectionProvider);
return connectionProvider;
}
return provider;
View on GitHub (pinned to e1c734241f)
Solutions
- Fix getDefaultTenantId() to always return a non-null value (provide a real default tenant)
- If tenant comes from the request, ensure the call happens inside an active request context or capture it earlier
- Throw a domain-specific exception when the tenant is truly unknown instead of returning null
- Add a test covering unauthenticated/no-tenant requests
Example fix
// before
@Override
public String getDefaultTenantId() {
return httpHeaders.getHeaderString("X-Tenant"); // may be null
}
// after
@Override
public String getDefaultTenantId() {
String tenant = httpHeaders.getHeaderString("X-Tenant");
if (tenant == null) {
throw new WebApplicationException("Missing tenant", 400);
}
return tenant;
} Defensive patterns
Strategy: validation
Validate before calling
String tenant = resolveTenantFromContext();
if (tenant == null || tenant.isBlank()) {
throw new IllegalStateException("Tenant id must not be null/blank before Hibernate calls");
} Type guard
boolean validTenant(String t) { return t != null && !t.isBlank(); } Try / catch
try {
return session.withTransaction(s -> s.find(E.class, id)).await().indefinitely();
} catch (IllegalStateException e) {
if (e.getMessage().contains("getDefaultTenantId")) { logMissingTenant(); }
throw e;
} Prevention
- Never return null from TenantResolver methods — throw a domain exception instead
- Ensure tenant extraction happens inside the active request/Vert.x context
- Test the no-authenticated-user path explicitly
When it happens
Trigger: Multi-tenant Hibernate ORM is active, getDefaultTenantId() is invoked (e.g., when the tenant connection provider must fall back to the default tenant / 'any' connection provider), and the user implementation returns null.
Common situations: Tenant id source not populated yet (e.g., reading tenant from a request header outside of an active request context, no request scope, Vert.x context absent); resolver method returns null instead of a default tenant; missing @ActivateRequestContext or context propagation.
Related errors
- Method 'TenantConnectionResolver.resolve(String)' returned a
- No instance of %1$s was found for persistence unit %2$s. You
- No instance of %1$s was found for persistence unit %2$s. You
- No instance of %1$s was found for persistence unit %2$s. You
- Methods that are annotated with JPA Listener annotations sho
AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05).
Data as JSON: /api/errors/4e107de899c839c5.
Report an issue: GitHub.