quarkusio/quarkus · error · IllegalStateException
Multiple instances of %1$s were found for persistence unit %
Error message
Multiple instances of %1$s were found for persistence unit %2$s. At most one instance can be assigned to each persistence unit. Instances found: %3$s
What it means
PersistenceUnitUtil enforces that at most one bean of a given extension type (e.g. a single Persistencer/KnownPersistenceUnit holder or interceptor) is assigned to a given persistence unit. When the CDI InjectableInstance for (beanType, PU name, qualifiers) resolves ambiguously — multiple beans match — this IllegalStateException is thrown listing all found bean classes.
Source
Thrown at extensions/hibernate-orm/runtime/src/main/java/io/quarkus/hibernate/orm/runtime/PersistenceUnitUtil.java:48
public static Annotation qualifier(String persistenceUnitName) {
if (isDefaultPersistenceUnit(persistenceUnitName)) {
return Default.Literal.INSTANCE;
} else {
return new PersistenceUnit.PersistenceUnitLiteral(persistenceUnitName);
}
}
public static <T> InjectableInstance<T> singleExtensionInstanceForPersistenceUnit(
Class<T> beanType,
String persistenceUnitName,
Annotation... additionalQualifiers) {
InjectableInstance<T> instance = extensionInstancesForPersistenceUnit(beanType, persistenceUnitName,
additionalQualifiers);
if (instance.isAmbiguous()) {
List<String> ambiguousClassNames = instance.handlesStream().map(h -> h.getBean().getBeanClass().getCanonicalName())
.toList();
throw new IllegalStateException(String.format(Locale.ROOT,
"Multiple instances of %1$s were found for persistence unit %2$s. "
+ "At most one instance can be assigned to each persistence unit. Instances found: %3$s",
beanType.getSimpleName(), persistenceUnitName, ambiguousClassNames));
}
return instance;
}
public static <T> InjectableInstance<T> extensionInstancesForPersistenceUnit(
Class<T> beanType,
String persistenceUnitName,
Annotation... additionalQualifiers) {
if (additionalQualifiers.length == 0) {
return Arc.container().select(beanType, new PersistenceUnitExtension.Literal(persistenceUnitName));
} else {
Annotation[] qualifiers = Arrays.copyOf(additionalQualifiers, additionalQualifiers.length + 1);
qualifiers[additionalQualifiers.length] = new PersistenceUnitExtension.Literal(persistenceUnitName);
return Arc.container().select(beanType, qualifiers);
}View on GitHub (pinned to e1c734241f)
Solutions
- Keep exactly one bean of that type per persistence unit, or annotate each with a distinct @PersistenceUnitExtension qualifier (e.g. @ReactiveTenantConnectionResolver variants).
- Use @Alternative/@Priority to disable one of the duplicate beans.
- Inspect the 'Instances found' list in the message and remove or qualify the redundant class.
- For multi-PU apps, narrow each bean with @PersistenceUnitExtension(persistenceUnitName = "...").
Example fix
// before (two beans for same PU)
@PersistenceUnitExtension class MyProviderA implements ... {}
@PersistenceUnitExtension class MyProviderB implements ... {}
// after
@PersistenceUnitExtension(persistenceUnitName = "pu1") class MyProviderA implements ... {}
@PersistenceUnitExtension(persistenceUnitName = "pu2") class MyProviderB implements ... {} Defensive patterns
Strategy: validation
Validate before calling
// Validate unambiguity at startup instead of at first use
InjectableInstance<T> i = instance.select(beanType, qualifiers);
if (i.isAmbiguous()) { throw new IllegalArgumentException("Multiple " + beanType + " beans for PU"); } Prevention
- One extension bean per persistence unit; use @PersistenceUnitExtension qualifiers to disambiguate
- Review the 'Instances found' list to locate the duplicate class quickly
- Use @Alternative + @Priority when overriding a built-in extension bean
When it happens
Trigger: Declaring two CDI beans of the same extension interface/class (e.g. two custom Persisters, two TenantConnectionProviders) both applicable to the same PU; beans with qualifiers that don't exclude each other; accidentally annotating a second class with the same @PersistenceUnitExtension qualifier/scope.
Common situations: Multi-tenancy setups where a developer adds a second extension bean per tenant but forgets @PersistenceUnitExtensionqualifiers; copy-pasting a CDI bean class; @Alternative not declared so both beans are enabled.
Related errors
- Multiple ${AdditionalPersistenceUnitBuildItem} for persisten
- This PersistenceProvider does not support createEntityManage
- No name provided and multiple persistence units found
- Attempting to boot a deactivated Hibernate ORM persistence u
- Unable to find an EntityManagerFactory for persistence unit
AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05).
Data as JSON: /api/errors/1835426dad0e1ded.
Report an issue: GitHub.