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 backend %2$s. At most one instance can be assigned to each backend. Instances found: %3$s

What it means

Same resolution logic as the index-scope variant: singleExtensionBeanReferenceFor() found multiple beans of the requested type whose qualifiers map to the same backend (backendName != null, indexName == null). Since at most one bean may be assigned per backend, the util throws IllegalStateException with the conflicting bean class names.

Source

Thrown at extensions/hibernate-search-standalone-elasticsearch/runtime/src/main/java/io/quarkus/hibernate/search/standalone/elasticsearch/runtime/bean/HibernateSearchBeanUtil.java:39

    public static <T> Optional<BeanReference<T>> singleExtensionBeanReferenceFor(Optional<String> override, Class<T> beanType,
            String backendName, String indexName) {
        return override.map(string -> BeanReference.parse(beanType, string))
                .or(() -> singleExtensionBeanReferenceFor(beanType, backendName, indexName));
    }

    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))

View on GitHub (pinned to e1c734241f)

Solutions

  1. Delete one of the conflicting backend-scoped beans listed in 'Instances found'.
  2. Restrict each bean to a narrower scope (add index = ...) or move one to another backend name so only one bean matches per backend.
  3. Change the backend attribute on the beans' @HibernateSearchExtension annotation so they target different backends.
  4. If a built-in extension bean conflicts with yours, check the docs for the config property that disables/exposes the built-in one.

Example fix

// before: two backend-wide beans for the same backend
@HibernateSearchExtension(backend = "elasticsearch")
@ApplicationScoped public class ClientA implements HttpClientFactory { ... }
@HibernateSearchExtension(backend = "elasticsearch")
@ApplicationScoped public class ClientB implements HttpClientFactory { ... }

// after: only one backend-wide bean remains
@HibernateSearchExtension(backend = "elasticsearch")
@ApplicationScoped public class ClientA implements HttpClientFactory { ... }
Defensive patterns

Strategy: validation

Validate before calling

// Backend-scoped ambiguity check before startup finishes
InjectableInstance<MyType> i = Arc.container().select(MyType.class, backendQualifier);
if (i.isAmbiguous()) {
    throw new IllegalStateException("Multiple backend-level beans for backend 'elasticsearch'");
}

Type guard

public static <T> boolean hasSingleBackendBean(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, backendName, null);
} catch (IllegalStateException e) {
    log.errorf("Backend '%s' has multiple candidate beans — remove or re-qualify one", backendName, e);
}

Prevention

When it happens

Trigger: Two or more beans of beanType are annotated @HibernateSearchExtension(...) targeting the same backend (e.g. backend = "elasticsearch") without an index restriction, making the backend-scoped lookup ambiguous.

Common situations: Providing two backend-level customizations (e.g. two HttpClientFactory or two entity loader implementations) for one named backend; one bean intended for a different backend configured with the wrong backend name; leftover bean from a copy-paste.

Related errors


AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05). Data as JSON: /api/errors/d5406b8cd215b71f. Report an issue: GitHub.