spring-projects/spring-framework · error · IllegalArgumentException
Qualifier type [{}] needs to be annotation type
Error message
Qualifier type [{}] needs to be annotation type What it means
Thrown by CustomAutowireConfigurer when a resolved custom qualifier type is not an annotation type (i.e., does not extend java.lang.annotation.Annotation). After resolving the Class or String to a Class object, the check Annotation.class.isAssignableFrom(customType) at line 114 fails for non-annotation classes.
Source
Thrown at spring-beans/src/main/java/org/springframework/beans/factory/annotation/CustomAutowireConfigurer.java:115
if (!(dlbf.getAutowireCandidateResolver() instanceof QualifierAnnotationAutowireCandidateResolver)) {
dlbf.setAutowireCandidateResolver(new QualifierAnnotationAutowireCandidateResolver());
}
QualifierAnnotationAutowireCandidateResolver resolver =
(QualifierAnnotationAutowireCandidateResolver) dlbf.getAutowireCandidateResolver();
for (Object value : this.customQualifierTypes) {
Class<? extends Annotation> customType = null;
if (value instanceof Class) {
customType = (Class<? extends Annotation>) value;
}
else if (value instanceof String className) {
customType = (Class<? extends Annotation>) ClassUtils.resolveClassName(className, this.beanClassLoader);
}
else {
throw new IllegalArgumentException(
"Invalid value [" + value + "] for custom qualifier type: needs to be Class or String.");
}
if (!Annotation.class.isAssignableFrom(customType)) {
throw new IllegalArgumentException(
"Qualifier type [" + customType.getName() + "] needs to be annotation type");
}
resolver.addQualifierType(customType);
}
}
}
}
View on GitHub (pinned to 69bf83ad71)
Solutions
- Ensure the specified type is a Java annotation (declared with @interface).
- Create a proper custom qualifier annotation annotated with @Target and @Retention.
- Verify the class name resolves to an annotation type, not a regular class or interface.
Example fix
// before
configurer.setCustomQualifierTypes(
Set.of(MyService.class)); // regular class, not annotation
// after
@Target({ElementType.FIELD, ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
@Qualifier
public @interface MyQualifier { }
configurer.setCustomQualifierTypes(
Set.of(MyQualifier.class)); // annotation type Defensive patterns
Strategy: validation
Validate before calling
// Validate that each qualifier type is an annotation before registering
for (Object value : customQualifierTypes) {
Class<?> type = (value instanceof Class<?> c) ? c
: ClassUtils.resolveClassName((String) value, classLoader);
if (!Annotation.class.isAssignableFrom(type)) {
throw new IllegalArgumentException(
type.getName() + " is not an annotation type");
}
} Type guard
// Type guard: ensure a class is an annotation before using as qualifier
static boolean isQualifierAnnotation(Class<?> type) {
return type != null && Annotation.class.isAssignableFrom(type);
} Prevention
- Custom qualifier types must be Java annotations (declared with @interface).
- Verify each type with Annotation.class.isAssignableFrom() before adding it.
- Create proper qualifier annotations annotated with @Target and @Retention(RUNTIME).
When it happens
Trigger: Specifying a regular class or interface (not annotated with @Target/@Retention/@interface) as a custom qualifier type. For example, passing com.example.SomeService.class (a regular class) instead of a custom @Qualifier-style annotation.
Common situations: Confusing a service/component class with a qualifier annotation. Typing the wrong fully-qualified class name in XML, resolving to a non-annotation class. Passing an interface that is not an annotation interface.
Related errors
- CustomAutowireConfigurer needs to operate on a DefaultListab
- Invalid value [{}] for custom qualifier type: needs to be Cl
- Lifecycle annotation requires a no-arg method:
- Value annotation must have a value attribute
- Cannot invoke instance method without factoryBeanName:
AI-assisted analysis of spring-projects/spring-framework@69bf83ad71 (2026-08-09).
Data as JSON: /api/errors/2deb0be9252a5c56.
Report an issue: GitHub.