spring-projects/spring-framework · error · IllegalArgumentException

Invalid value [{}] for custom qualifier type: needs to be Cl

Error message

Invalid value [{}] for custom qualifier type: needs to be Class or String.

What it means

Thrown by CustomAutowireConfigurer when iterating customQualifierTypes and encountering an element that is neither a Class nor a String. The setCustomQualifierTypes(Set<?>) accepts arbitrary objects, but each must be a Class literal or a fully-qualified class name String.

Source

Thrown at spring-beans/src/main/java/org/springframework/beans/factory/annotation/CustomAutowireConfigurer.java:111

			if (!(beanFactory instanceof DefaultListableBeanFactory dlbf)) {
				throw new IllegalStateException(
						"CustomAutowireConfigurer needs to operate on a DefaultListableBeanFactory");
			}
			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

  1. Ensure every element in customQualifierTypes is either a Class object or a fully-qualified annotation class name String.
  2. In XML, use <value>com.example.MyQualifier</value> (String) or <value type="java.lang.Class">com.example.MyQualifier</value>.
  3. Audit the set contents at configuration time.

Example fix

<!-- before -->
<bean class="...CustomAutowireConfigurer">
  <property name="customQualifierTypes">
    <set>
      <value>12345</value> <!-- invalid -->
    </set>
  </property>
</bean>

<!-- after -->
<bean class="...CustomAutowireConfigurer">
  <property name="customQualifierTypes">
    <set>
      <value>com.example.MyQualifierAnnotation</value>
    </set>
  </property>
</bean>
Defensive patterns

Strategy: validation

Validate before calling

// Validate all custom qualifier type entries before passing to configurer
for (Object value : customQualifierTypes) {
    if (!(value instanceof Class) && !(value instanceof String)) {
        throw new IllegalArgumentException(
            "Invalid custom qualifier type entry: " + value
            + " (must be Class or String)");
    }
}

Prevention

When it happens

Trigger: Configuring customQualifierTypes with values that are not Class or String — e.g., an Integer, an enum, or an Annotation instance passed into the set via XML property injection or programmatic configuration.

Common situations: XML misconfiguration where <value> elements are parsed to non-string types. Programmatic configuration where a wrong type is added to the set. A typo in XML causing a value tag to be interpreted as a non-string type.

Related errors


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