quarkusio/quarkus · error · RuntimeException
Cannot handle wildcard type
Error message
Cannot handle wildcard type
What it means
When converting indexed types to class names, EndpointIndexer.toClassName cannot represent a wildcard type with an unbounded/Object bound (e.g. ? or List<?>). Only wildcards with a meaningful extends bound are supported (the bound is used instead). It throws a RuntimeException, typically surfaced wrapped by error 3383.
Source
Thrown at independent-projects/resteasy-reactive/common/processor/src/main/java/org/jboss/resteasy/reactive/common/processor/EndpointIndexer.java:1149
protected static String toClassName(Type indexType, ClassInfo currentClass, ClassInfo actualEndpointClass,
IndexView indexView) {
switch (indexType.kind()) {
case VOID:
return "void";
case CLASS:
return indexType.asClassType().name().toString();
case PRIMITIVE:
return indexType.asPrimitiveType().primitive().name().toLowerCase(Locale.ENGLISH);
case PARAMETERIZED_TYPE:
return indexType.asParameterizedType().name().toString();
case ARRAY:
return indexType.asArrayType().name().toString();
case WILDCARD_TYPE:
WildcardType wildcardType = indexType.asWildcardType();
Type extendsBound = wildcardType.extendsBound();
if (extendsBound.name().equals(OBJECT)) {
// this is a super bound type that we don't support
throw new RuntimeException("Cannot handle wildcard type " + indexType);
}
// this is an extend bound type, so we just user the bound
return wildcardType.name().toString();
case TYPE_VARIABLE:
TypeVariable typeVariable = indexType.asTypeVariable();
if (typeVariable.bounds().isEmpty()) {
return Object.class.getName();
}
return toClassName(resolveTypeVariable(typeVariable, currentClass, actualEndpointClass, indexView),
currentClass, actualEndpointClass, indexView);
default:
throw new RuntimeException("Unknown parameter type " + indexType);
}
}
private static Type resolveTypeVariable(TypeVariable typeVariable, ClassInfo currentClass, ClassInfo actualEndpointClass,
IndexView indexView) {View on GitHub (pinned to e1c734241f)
Solutions
- Replace the unbounded wildcard with a concrete type (e.g. List<String> instead of List<?>)
- Use an explicit extends bound (e.g. List<? extends Number>) if subtype flexibility is needed
- Move the wildcard-typed logic out of the endpoint signature into internal code with concrete types
Example fix
// before
@GET
public List<?> list() { ... }
// after
@GET
public List<String> list() { ... } Defensive patterns
Strategy: type-guard
Validate before calling
static <T> Class<T> requireConcrete(java.lang.reflect.Type t) {
if (t instanceof ParameterizedType pt) {
for (java.lang.reflect.Type arg : pt.getActualTypeArguments()) {
if (arg instanceof WildcardType wt
&& (wt.getUpperBounds().length == 0 || wt.getUpperBounds()[0] == Object.class)
&& wt.getLowerBounds().length == 0)
throw new IllegalArgumentException("Unbounded wildcard not allowed: " + t);
requireConcrete(arg);
}
}
return null;
} Type guard
static boolean isSupportedEndpointType(java.lang.reflect.Type t) {
if (t instanceof WildcardType wt) {
return wt.getUpperBounds().length > 0 && wt.getUpperBounds()[0] != Object.class;
}
if (t instanceof ParameterizedType pt) {
return java.util.Arrays.stream(pt.getActualTypeArguments())
.allMatch(MyChecks::isSupportedEndpointType);
}
return !(t instanceof WildcardType);
} Prevention
- Avoid unbounded wildcards (List<?>, Map<?,?>) in endpoint signatures
- Prefer concrete types or explicit extends bounds for generics in REST APIs
- Keep generic flexibility in internal service code, not the REST layer
- Compile endpoints early with quarkus:dev to catch indexing failures
When it happens
Trigger: A resource method signature uses an unbounded wildcard generic such as List<?>, Map<String,?>, or a parameter/return type of ? with no extends bound, and Quarkus indexes the endpoint.
Common situations: Generic helper signatures reused in resource methods; returning ResponseEntity<List<?>> style types; copy-pasting repository/DAO generic types into endpoints.
Related errors
- Unknown parameter type
- Failed to find Collection supertype of ${field}
- Unsupported wildcard type: ${wildcard}
- Unsupported type: " + type
- Parameter: ${i} of the constructor of class '${resourceDotNa
AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05).
Data as JSON: /api/errors/67290bfec6bfdcb9.
Report an issue: GitHub.