quarkusio/quarkus · error · IllegalArgumentException
Using @UnwrapException without a value is only supported on
Error message
Using @UnwrapException without a value is only supported on exception classes. Offending target is '${classInfo.name()}'. What it means
When @UnwrapException is used without a value on a class, Quarkus requires the class (or one of its superclasses) to be a java.lang.Exception/Throwable type, since the class itself is treated as the exception to unwrap. If the hierarchy walk never reaches an exception type, deployment fails with this IllegalArgumentException.
Source
Thrown at extensions/resteasy-reactive/rest/deployment/src/main/java/io/quarkus/resteasy/reactive/server/deployment/ResteasyReactiveScanningProcessor.java:177
throw new IllegalStateException(
"@UnwrapException is only supported on classes. Offending target is: " + target);
}
ClassInfo classInfo = target.asClass();
ClassInfo toCheck = classInfo;
boolean isException = false;
while (true) {
DotName superDotName = toCheck.superName();
if (EXCEPTION.equals(superDotName) || RUNTIME_EXCEPTION.equals(superDotName)) {
isException = true;
break;
}
toCheck = index.getClassByName(superDotName);
if (toCheck == null) {
break;
}
}
if (!isException) {
throw new IllegalArgumentException(
"Using @UnwrapException without a value is only supported on exception classes. Offending target is '"
+ classInfo.name() + "'.");
}
producer.produce(new UnwrappedExceptionBuildItem(classInfo.name().toString(), strategy));
} else {
Type[] exceptionTypes = value.asClassArray();
for (Type exceptionType : exceptionTypes) {
producer.produce(new UnwrappedExceptionBuildItem(exceptionType.name().toString(), strategy));
}
}
}
}
private static ExceptionUnwrapStrategy toExceptionUnwrapStrategy(AnnotationValue strategyValue) {
if (strategyValue != null) {
return ExceptionUnwrapStrategy.valueOf(strategyValue.asEnum());
}View on GitHub (pinned to e1c734241f)
Solutions
- Make the annotated class extend RuntimeException or another Throwable subtype
- Provide an explicit value naming the exception to unwrap: @UnwrapException(MyException.class)
- Remove @UnwrapException if the class is not involved in exception unwrapping
- If a superclass should have matched, ensure it is part of the Quarkus index (proper module dependency, not an unindexed jar)
Example fix
// before
@UnwrapException
public class ResultWrapper { ... }
// after
@UnwrapException
public class ResultWrapper extends RuntimeException { ... } Defensive patterns
Strategy: validation
Validate before calling
UnwrapException u = clazz.getAnnotation(UnwrapException.class);
if (u != null && u.value() == UnwrapException.class /* no value */
&& !Throwable.class.isAssignableFrom(clazz))
throw new IllegalStateException(clazz + " uses @UnwrapException without value but is not an exception class"); Prevention
- Ensure classes annotated with value-less @UnwrapException extend Exception/RuntimeException
- Otherwise pass the target exception type as the annotation value
- Keep exception hierarchies in indexed application modules so superclass checks succeed
When it happens
Trigger: @UnwrapException (no value) is placed on a class that does not extend Throwable/Exception (checked by walking superclasses in the Jandex index; also breaks early if a superclass is not in the index), e.g. on a plain POJO or a resource class.
Common situations: Annotating a wrapper class that is not an exception, intending custom unwrapping logic; renaming/refactoring so the annotated class no longer extends Exception; missing superclass in the index (separate module not indexed).
Related errors
- @UnwrapException is only supported on classes. Offending tar
- Cannot have more than one of @PathParam, @QueryParam, @Heade
- No annotations found on fields at '%s'. Annotations like `@Q
- A resource method cannot be simultaneously annotated with '@
- Value not set for ${param}
AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05).
Data as JSON: /api/errors/efc6dac5e2e24854.
Report an issue: GitHub.