quarkusio/quarkus · error · IllegalStateException
Method 'TenantResolver.resolveTenantId()' returned a null va
Error message
Method 'TenantResolver.resolveTenantId()' returned a null value. Unfortunately Hibernate ORM does not allow null for tenant identifiers. Please use a non-null value!
What it means
Hibernate ORM forbids null tenant identifiers. Quarkus' HibernateCurrentTenantIdentifierResolver calls the application's TenantResolver.resolveTenantId() and throws IllegalStateException when it returns null, telling you to return a non-null value.
Source
Thrown at extensions/hibernate-orm/runtime/src/main/java/io/quarkus/hibernate/orm/runtime/tenant/HibernateCurrentTenantIdentifierResolver.java:40
private final String persistenceUnitName;
public HibernateCurrentTenantIdentifierResolver(String persistenceUnitName) {
this.persistenceUnitName = persistenceUnitName;
}
@Override
public String resolveCurrentTenantIdentifier() {
// Make sure that we're in a request
if (!Arc.container().requestContext().isActive()) {
return null;
}
TenantResolver resolver = tenantResolver(persistenceUnitName);
String tenantId = resolver.resolveTenantId();
if (tenantId == null) {
throw new IllegalStateException("Method 'TenantResolver.resolveTenantId()' returned a null value. "
+ "Unfortunately Hibernate ORM does not allow null for tenant identifiers. "
+ "Please use a non-null value!");
}
LOG.debugv("resolveCurrentTenantIdentifier(): {0}", tenantId);
return tenantId;
}
@Override
public boolean validateExistingCurrentSessions() {
return false;
}
@Override
public boolean isRoot(String tenantId) {
// Make sure that we're in a request
if (!Arc.container().requestContext().isActive()) {
return false;View on GitHub (pinned to e1c734241f)
Solutions
- Return a non-null default tenant id from resolveTenantId() when no tenant context is available
- Reject the request earlier (e.g. in a filter/interceptor) when the tenant identifier is missing, before Hibernate resolves it
- Make the resolver fail fast with your own descriptive exception (e.g. 400 Bad Request) instead of returning null
- Test with an explicit tenant header/path so the resolver never receives null input
Example fix
// before
public String resolveTenantId() {
return headers.getHeaderString("X-Tenant"); // may be null -> throws
}
// after
public String resolveTenantId() {
String t = headers.getHeaderString("X-Tenant");
return t != null ? t : "default";
} Defensive patterns
Strategy: validation
Validate before calling
String tenantId = resolver.resolveTenantId();
if (tenantId == null) {
tenantId = "default"; // or reject request before Hibernate resolves tenants
} Type guard
Optional<String> safeTenant(TenantResolver r) {
return Optional.ofNullable(r.resolveTenantId());
} Try / catch
try {
doJpaWork();
} catch (IllegalStateException e) {
if (e.getMessage().contains("returned a null value")) {
Log.error("TenantResolver returned null; provide a default or reject the request");
throw new BadRequestException("Missing tenant context");
}
throw e;
} Prevention
- Never return null from resolveTenantId(); fall back to a default tenant
- Reject requests lacking tenant context in a filter before Hibernate runs
- Cover unauthenticated endpoints in tests since they bypass tenant extraction
When it happens
Trigger: A registered TenantResolver whose resolveTenantId() returns null at runtime — e.g. no tenant context in the request (missing header/path segment), unauthenticated request where the resolver derives the tenant from the security identity, or a test/mock resolver returning null.
Common situations: Resolver extracting tenant from an HTTP header that isn't present; SecurityIdentity-dependent resolver hit on the login/unauthenticated endpoint; forgetting a default/fallback tenant id for non-tenant endpoints.
Related errors
- Unexpected multitenancy strategy:
- Fruit with id of {id} does not exist.
- Methods that are annotated with JPA Listener annotations sho
- An extension attempted to contribute the default persistence
- Persistence unit '%s' is contributed by an extension but is
AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05).
Data as JSON: /api/errors/5e487a5697e33c27.
Report an issue: GitHub.