quarkusio/quarkus · error · IllegalStateException
AnnotationInstance <annotationInstance> is an invalid target
Error message
AnnotationInstance <annotationInstance> is an invalid target. Only Method targets are supported
What it means
The Spring DI extension derives bean names from @Bean methods in configuration classes. This method expects the @Bean annotation instance to target a method; when the target is not a method, the build fails with this IllegalStateException. @Bean is only meaningful on methods producing beans.
Source
Thrown at extensions/spring-di/deployment/src/main/java/io/quarkus/spring/di/deployment/SpringDIProcessor.java:518
private String getBeanNameFromStereotypeInstance(AnnotationInstance annotationInstance) {
if (annotationInstance.target().kind() != AnnotationTarget.Kind.CLASS) {
throw new IllegalStateException(
"AnnotationInstance " + annotationInstance + " is an invalid target. Only Class targets are supported");
}
final AnnotationValue value = annotationInstance.value();
if ((value == null) || value.asString().isEmpty()) {
return getDefaultBeanNameFromClass(annotationInstance.target().asClass().name().toString());
} else {
return value.asString();
}
}
/**
* Meant to be called with instances of @Bean
*/
private String getBeanNameFromBeanInstance(AnnotationInstance annotationInstance) {
if (annotationInstance.target().kind() != AnnotationTarget.Kind.METHOD) {
throw new IllegalStateException(
"AnnotationInstance " + annotationInstance + " is an invalid target. Only Method targets are supported");
}
String beanName = null;
final AnnotationValue beanNameAnnotationValue = annotationInstance.value("name");
if (beanNameAnnotationValue != null) {
beanName = determineName(beanNameAnnotationValue);
}
if (beanName == null || beanName.isEmpty()) {
final AnnotationValue beanValueAnnotationValue = annotationInstance.value();
if (beanValueAnnotationValue != null) {
beanName = determineName(beanValueAnnotationValue);
}
}
if (beanName == null || beanName.isEmpty()) {
beanName = annotationInstance.target().asMethod().name();
}
View on GitHub (pinned to e1c734241f)
Solutions
- Move @Bean to a public method inside a @Configuration class that returns the bean
- Remove @Bean from classes/fields; annotate those with @Component or inject via constructor
- If a custom annotation composes @Bean, restrict it to @Target(METHOD)
- Re-index and confirm no stray @Bean annotation instances exist on non-method targets
Example fix
// before
@Bean
public class MyConfig { }
// after
@Configuration
public class MyConfig {
@Bean
public MyService myService() { return new MyService(); }
} Defensive patterns
Strategy: validation
Validate before calling
// Place @Bean only on methods:
@Configuration
public class MyConfig {
@Bean // method target only
public MyService myService() { return new MyService(); }
}
// Composed annotations: @Target(ElementType.METHOD) Prevention
- Annotate @Bean only on @Configuration class methods
- Never put @Bean on classes or fields
- Constrain composed annotations with @Target(ElementType.METHOD)
- Review annotation placement after using migration tooling
When it happens
Trigger: @Bean found on a non-method target (class, field, parameter) — typically via misuse, a typo, or a meta-annotation that drags @Bean onto a class/field during index scanning.
Common situations: Copy-paste of @Bean onto a configuration class; applying @Bean to fields intending field injection; custom annotations annotated with @Bean; migration tooling misplacing annotations.
Related errors
- AnnotationInstance ${instance} is an invalid target. Only Cl
- The @Blocking, @NonBlocking and @RunOnVirtualThread annotati
- Value not set for ${param}
- TransformedAnnotationsBuildItem#queryForMethodParam needs to
- @CachedResults class must be an interface or declare a no-ar
AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05).
Data as JSON: /api/errors/6386cd7e017db8d6.
Report an issue: GitHub.