apache/dubbo · error · ScopeBeanException

expected single matching bean but found ${size} candidates f

Error message

expected single matching bean but found ${size} candidates for type [${type}]: ${candidateBeanNames}

What it means

Thrown by ScopeBeanFactory.getBeanInternal when resolving by type only (or with a name that does not exactly match) and more than one registered bean is assignable to the requested type. Dubbo cannot guess which instance to return, so it lists the candidate bean names and aborts. This mirrors Spring's NoUniqueBeanDefinitionException.

Source

Thrown at dubbo-common/src/main/java/org/apache/dubbo/common/beans/factory/ScopeBeanFactory.java:348

                    } else {
                        if (candidates == null) {
                            candidates = new ArrayList<>();
                            candidates.add(firstCandidate);
                        }
                        candidates.add(beanInfo);
                    }
                }
            }
        }

        // if bean name not matched and only single candidate
        if (candidates != null) {
            if (candidates.size() == 1) {
                return (T) candidates.get(0).instance;
            } else if (candidates.size() > 1) {
                List<String> candidateBeanNames =
                        candidates.stream().map(beanInfo -> beanInfo.name).collect(Collectors.toList());
                throw new ScopeBeanException("expected single matching bean but found " + candidates.size()
                        + " candidates for type [" + type.getName() + "]: " + candidateBeanNames);
            }
        } else if (firstCandidate != null) {
            return (T) firstCandidate.instance;
        }
        return null;
    }

    public void destroy() {
        if (destroyed.compareAndSet(false, true)) {
            for (BeanInfo beanInfo : registeredBeanInfos) {
                if (beanInfo.instance instanceof Disposable) {
                    try {
                        Disposable beanInstance = (Disposable) beanInfo.instance;
                        beanInstance.destroy();
                    } catch (Throwable e) {
                        LOGGER.error(
                                CONFIG_FAILED_DESTROY_INVOKER,

View on GitHub (pinned to 3a3043227f)

Solutions

  1. Request the bean by the exact name of one of the candidates listed in the message.
  2. Make the bean name match when registering, so getBean(name, type) resolves uniquely.
  3. Reduce to a single bean of that type in the scope, or mark one as primary/removable for your use case.
  4. If you need all instances, use an injection point for a List<T> / iterate registered beans instead of getBean.

Example fix

// before
factory.registerBean("a", MyImpl.class);
factory.registerBean("b", MyImpl.class);
MyApi bean = factory.getBean(MyApi.class);  // ambiguous -> error
// after
MyApi bean = factory.getBean("a", MyApi.class);  // exact name match
Defensive patterns

Strategy: validation

Validate before calling

// Count assignable candidates before resolving by type
<T> long candidateCount(ScopeBeanFactory f, Class<T> type) {
    // public getBean throws on ambiguity; instead detect by attempting exact names
    long n = 0;
    for (String name : knownNames) {
        if (f.getBean(name, type) != null) n++;
    }
    return n;
}

Try / catch

try {
    T bean = factory.getBean(type);
} catch (ScopeBeanException e) {
    if (e.getMessage().startsWith("expected single matching bean")) {
        // parse candidate names from the message and pick one explicitly:
        // bean = factory.getBean(candidateName, type);
    } else throw e;
}

Prevention

When it happens

Trigger: Calling getBean(type) or getBean(name, type) where name does not equal any registered bean's name, and two or more beans assignable to type exist. Common when multiple implementations of an interface/SPI are registered in the same scope.

Common situations: Multiple @DubboService implementations of the same interface; two beans of compatible types registered by different modules sharing a ScopeBeanFactory; custom extensions that register duplicate-type beans; requesting an interface bean without a qualifier.

Related errors


AI-assisted analysis of apache/dubbo@3a3043227f (2026-08-14). Data as JSON: /api/errors/8b644584db561847. Report an issue: GitHub.