quarkusio/quarkus · error · IllegalStateException
Multiple instances of %1$s were found for Hibernate Search S
Error message
Multiple instances of %1$s were found for Hibernate Search Standalone. At most one instance can be assigned. Instances found: %2$s
What it means
Global-scope variant of the ambiguity check: when neither an index nor backend name applies, singleExtensionBeanReferenceFor() requires exactly one bean of beanType in the whole Hibernate Search Standalone context. If multiple globally-qualified beans of that type exist, it throws IllegalStateException enumerating them.
Source
Thrown at extensions/hibernate-search-standalone-elasticsearch/runtime/src/main/java/io/quarkus/hibernate/search/standalone/elasticsearch/runtime/bean/HibernateSearchBeanUtil.java:44
private static <T> Optional<BeanReference<T>> singleExtensionBeanReferenceFor(Class<T> beanType,
String backendName, String indexName) {
InjectableInstance<T> instance = extensionInstanceFor(beanType, backendName, indexName);
if (instance.isAmbiguous()) {
List<String> ambiguousClassNames = instance.handlesStream().map(h -> h.getBean().getBeanClass().getCanonicalName())
.toList();
if (indexName != null) {
throw new IllegalStateException(String.format(Locale.ROOT,
"Multiple instances of %1$s were found for Hibernate Search Standalone index %2$s."
+ " At most one instance can be assigned to each index. Instances found: %3$s",
beanType.getSimpleName(), indexName, ambiguousClassNames));
} else if (backendName != null) {
throw new IllegalStateException(String.format(Locale.ROOT,
"Multiple instances of %1$s were found for Hibernate Search Standalone backend %2$s."
+ " At most one instance can be assigned to each backend. Instances found: %3$s",
beanType.getSimpleName(), backendName, ambiguousClassNames));
} else {
throw new IllegalStateException(String.format(Locale.ROOT,
"Multiple instances of %1$s were found for Hibernate Search Standalone."
+ " At most one instance can be assigned. Instances found: %2$s",
beanType.getSimpleName(), ambiguousClassNames));
}
}
return instance.isResolvable() ? Optional.of(new ArcBeanReference<>(instance.getHandle().getBean())) : Optional.empty();
}
public static <T> Optional<List<BeanReference<T>>> multiExtensionBeanReferencesFor(Optional<List<String>> override,
Class<T> beanType,
String backendName, String indexName) {
return override.map(strings -> strings.stream()
.map(string -> BeanReference.parse(beanType, string))
.collect(Collectors.toList()))
.or(() -> multiExtensionBeanReferencesFor(beanType, backendName, indexName));
}
private static <T> Optional<List<BeanReference<T>>> multiExtensionBeanReferencesFor(Class<T> beanType,View on GitHub (pinned to e1c734241f)
Solutions
- Remove one of the globally-scoped beans listed in the 'Instances found' message.
- Target each bean to a specific backend or index via @HibernateSearchExtension(backend=.../index=...) so the global lookup resolves uniquely.
- Mark the undesired bean as @Vetoed or remove its bean-defining annotation so ArC ignores it.
- If intentional replacement is wanted, use @Alternative + @Priority instead of registering two beans side by side.
Example fix
// before: two global beans of the same type
@HibernateSearchExtension
@ApplicationScoped public class ObserverA implements MassIndexingObserver { ... }
@HibernateSearchExtension
@ApplicationScoped public class ObserverB implements MassIndexingObserver { ... }
// after: keep one, or target the other
@HibernateSearchExtension
@ApplicationScoped public class ObserverA implements MassIndexingObserver { ... }
// ObserverB deleted (or annotated with @Vetoed) Defensive patterns
Strategy: validation
Validate before calling
// Global-scope ambiguity check
InjectableInstance<MyType> i = Arc.container().select(MyType.class, hibernateSearchExtensionQualifier);
if (i.isAmbiguous()) {
throw new IllegalStateException("Multiple global Hibernate Search beans of " + MyType.class);
} Type guard
public static <T> boolean hasSingleGlobalBean(Class<T> type, Annotation... qualifiers) {
var instance = Arc.container().select(type, qualifiers);
return instance.isResolvable() && !instance.isAmbiguous();
} Try / catch
try {
Optional<BeanReference<T>> ref = HibernateSearchBeanUtil.singleExtensionBeanReferenceFor(beanType, null, null);
} catch (IllegalStateException e) {
log.errorf("Multiple global Hibernate Search Standalone beans found — keep one or add backend/index qualifiers: %s", e.getMessage(), e);
} Prevention
- Register at most one unqualified (global) bean per extension role.
- Use @Alternative with @Priority for intentional replacement instead of parallel beans.
- Annotate test-only beans with @Vetoed so they never enter production resolution.
- When the extension also provides a default bean, target yours to a backend/index or disable the default via config.
When it happens
Trigger: Two or more beans of beanType carry @HibernateSearchExtension without backend/index targeting (global scope), so the plain lookup is ambiguous and instance.isAmbiguous() fires.
Common situations: Registering two global customizations of the same role (e.g. two mass-indexing observers or two mapper beans) both annotated without scope qualifiers; leaving a test/alternative bean (@Alternative not active or both discovered) in the archive; adding an extension default bean plus your own global bean.
Related errors
- Multiple instances of %1$s were found for Hibernate Search i
- Multiple instances of %1$s were found for Hibernate Search b
- Multiple instances of %1$s were found for Hibernate Search i
- Multiple instances of %1$s were found for Hibernate Search S
- Multiple instances of %1$s were found for Hibernate Search S
AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05).
Data as JSON: /api/errors/73232bb666bc1347.
Report an issue: GitHub.