spring-projects/spring-framework · error · NoUniqueBeanDefinitionException

No qualifying bean of type '{}' available: more than 1 match

Error message

No qualifying bean of type '{}' available: more than 1 matching bean

What it means

NoUniqueBeanDefinitionException thrown by the default ObjectProvider.getObject() at line 93 when the iterator yields more than one bean. getObject() demands uniqueness; multiple candidates without a primary/qualifier resolution fail here. Use getIfUnique() for null-safe multi-candidate handling.

Source

Thrown at spring-beans/src/main/java/org/springframework/beans/factory/ObjectProvider.java:93

	 * but still excluding non-autowire candidates when used on injection points.
	 * @since 6.2.3
	 * @see #stream(Predicate)
	 * @see #orderedStream(Predicate)
	 * @see org.springframework.beans.factory.config.BeanDefinition#isAutowireCandidate()
	 * @see org.springframework.beans.factory.support.AbstractBeanDefinition#isDefaultCandidate()
	 */
	Predicate<Class<?>> UNFILTERED = (clazz -> true);


	@Override
	default T getObject() throws BeansException {
		Iterator<T> it = iterator();
		if (!it.hasNext()) {
			throw new NoSuchBeanDefinitionException(Object.class);
		}
		T result = it.next();
		if (it.hasNext()) {
			throw new NoUniqueBeanDefinitionException(Object.class, 2, "more than 1 matching bean");
		}
		return result;
	}

	/**
	 * Return an instance (possibly shared or independent) of the object
	 * managed by this factory.
	 * <p>Allows for specifying explicit construction arguments, along the
	 * lines of {@link BeanFactory#getBean(String, Object...)}.
	 * @param args arguments to use when creating a corresponding instance
	 * @return an instance of the bean
	 * @throws BeansException in case of creation errors
	 * @see #getObject()
	 */
	default T getObject(@Nullable Object... args) throws BeansException {
		throw new UnsupportedOperationException("Retrieval with arguments not supported -" +
				"for custom ObjectProvider classes, implement getObject(Object...) for your purposes");
	}

View on GitHub (pinned to 69bf83ad71)

Solutions

  1. Use getIfUnique() / getIfUnique(() -> default) / ifUnique(consumer) for multi-candidate providers.
  2. Mark one candidate @Primary or narrow with @Qualifier so a unique bean exists.
  3. Inject List<T> / Stream<T> via the provider when all candidates are wanted.

Example fix

// before
T bean = provider.getObject(); // throws if 2 candidates

// after
T bean = provider.getIfUnique(() -> fallback);
Defensive patterns

Strategy: fallback

Validate before calling

// Use the unique-safe accessor for possibly-ambiguous providers
T bean = provider.getIfUnique();
if (bean == null) { /* 0 or many; disambiguate */ }

Type guard

static <T> boolean isUnique(ObjectProvider<T> p) {
    return p.stream().count() == 1;
}

Prevention

When it happens

Trigger: objectProvider.getObject() where two or more beans of T are registered and none is resolved as primary; calling getObject() in code that assumed a single source.

Common situations: Two implementations of an interface; an interface plus a Mockito test double both active in a slice test; multiple DataSource beans.

Related errors


AI-assisted analysis of spring-projects/spring-framework@69bf83ad71 (2026-08-09). Data as JSON: /api/errors/16a51a54d2356bb5. Report an issue: GitHub.