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

  1. Make the annotated class extend RuntimeException or another Throwable subtype
  2. Provide an explicit value naming the exception to unwrap: @UnwrapException(MyException.class)
  3. Remove @UnwrapException if the class is not involved in exception unwrapping
  4. 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

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


AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05). Data as JSON: /api/errors/efc6dac5e2e24854. Report an issue: GitHub.