quarkusio/quarkus · error · IllegalStateException
Unsupported target:
Error message
Unsupported target:
What it means
During Quarkus build, the cache extension processes every @CachedResults annotation. @CachedResults is only allowed on an injection field or an injection method parameter; any other annotation target (e.g. a class, method, or type-use) is rejected. This is a build-time deployment error, not a runtime failure.
Source
Thrown at extensions/cache/deployment/src/main/java/io/quarkus/cache/deployment/CachedResultsProcessor.java:344
AnnotationValue lockTimeoutValue = annotation.value("lockTimeout");
if (lockTimeoutValue != null)
lockTimeout = lockTimeoutValue.asLong();
AnnotationValue keyGeneratorValue = annotation.value("keyGenerator");
if (keyGeneratorValue != null)
keyGenerator = keyGeneratorValue.asClass().name();
AnnotationValue excludeValue = annotation.value("exclude");
if (excludeValue != null)
exclude = excludeValue.asString();
if (annotation.target().kind() == Kind.FIELD) {
type = annotation.target().asField().type();
} else if (annotation.target().kind() == Kind.METHOD_PARAMETER) {
type = annotation.target().asMethodParameter().type();
} else {
throw new IllegalStateException("Unsupported target:" + annotation.target());
}
if (type.kind() != Type.Kind.CLASS) {
throw new IllegalStateException("Invalid type: " + type);
}
ClassInfo injectedClazz = index.getClassByName(type.name());
if (injectedClazz == null) {
throw new IllegalStateException("Injected class not found in index: " + type.name());
}
if (!injectedClazz.isInterface()
&& !injectedClazz.hasNoArgsConstructor()) {
throw new IllegalStateException(
"@CachedResults class must be an interface or declare a no-args constructor: " + injectedClazz);
}
return new CachedResultsInjectConfig(cacheName, lockTimeout, keyGenerator, injectedClazz,
// consider all but @CachedResults and @Inject
annotation.target().declaredAnnotations().stream().filter(
a -> !a.name().equals(CACHED_RESULTS)View on GitHub (pinned to e1c734241f)
Solutions
- Move @CachedResults onto the injected field: `@Inject @CachedResults MyInterface result;`
- If injected via constructor/setter, put it on the parameter: `public MyClass(@CachedResults MyInterface r) {...}`
- Never place @CachedResults on a class, plain (non-injection) method, or local variable.
Example fix
// before
@CachedResults
public class MyService { ... }
// after
public class MyService {
@Inject
@CachedResults(cacheName = "my-cache")
MyResultInterface result;
} Defensive patterns
Strategy: validation
Validate before calling
// Build-time check: only fields or method parameters of an injected point may carry @CachedResults // In application code, simply never place @CachedResults elsewhere; verify usage: // grep -rn --include='*.java' -B2 '@CachedResults' src/main/java | grep -E 'class |void |static '
Prevention
- Only apply @CachedResults next to @Inject (field or injection parameter)
- Let the IDE show the annotation's @Target and respect it
- Review annotation placement during code review for cache annotations
When it happens
Trigger: Placing @CachedResults on a target other than a FIELD or METHOD_PARAMETER — e.g. annotating the class itself, a business method, or a local variable while the deployment step walks injection points and calls createConfig.
Common situations: Developers copying @Inject-style annotation placement assumptions, annotating a constructor or setter instead of a field, or IDE quick-fixes moving the annotation to the wrong element.
Related errors
- Invalid type:
- Injected class not found in index:
- @CachedResults class must be an interface or declare a no-ar
- Unsupported annotation target kind
- Failed to open path tree with root %s
AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05).
Data as JSON: /api/errors/1caf6effdffc4643.
Report an issue: GitHub.