quarkusio/quarkus · error · IllegalStateException
Subresource method returns an invalid type: " + method.retur
Error message
Subresource method returns an invalid type: " + method.returnType().name()
What it means
ClientEndpointIndexer.handleClientSubResource throws this when a client interface subresource method returns a type that is not present in the build-time index. The indexer must scan the returned class to discover its own sub-endpoints, and ClassInfo for it could not be found (not indexed, not on the Jandex index, or not a class).
Source
Thrown at independent-projects/resteasy-reactive/client/processor/src/main/java/org/jboss/resteasy/reactive/client/processor/scanning/ClientEndpointIndexer.java:111
if (blockingAnnotation.target().annotation(CLIENT_EXCEPTION_MAPPER) == null) {
offendingBlockingAnnotations.add(blockingAnnotation);
}
}
}
if (!offendingBlockingAnnotations.isEmpty()
|| classInfo.annotationsMap().get(ResteasyReactiveDotNames.NON_BLOCKING) != null) {
log.warn(
"'@Blocking' and '@NonBlocking' annotations are not necessary (or supported) on REST Client interfaces. Offending class is '"
+ classInfo.name()
+ "'. Whether or not the call blocks the calling thread depends on the return type of the method - returning 'Uni', 'Multi' or 'CompletionStage' results in the implementation being non-blocking.");
}
}
@Override
protected void handleClientSubResource(ResourceMethod resourceMethod, MethodInfo method, IndexView index) {
ClassInfo subResourceClass = index.getClassByName(method.returnType().name());
if (subResourceClass == null) {
throw new IllegalStateException("Subresource method returns an invalid type: " + method.returnType().name());
}
List<ResourceMethod> endpoints = createEndpoints(subResourceClass, subResourceClass,
new HashSet<>(), new HashSet<>(), new HashSet<>(),
"", false);
resourceMethod.setSubResourceMethods(endpoints);
}
@Override
protected ResourceMethod createResourceMethod(MethodInfo info, ClassInfo actualEndpointClass,
Map<String, Object> methodContext) {
return new ResourceMethod();
}
@Override
protected boolean handleBeanParam(ClassInfo actualEndpointInfo, Type paramType, MethodParameter[] methodParameters, int i,
Set<String> fileFormNames) {View on GitHub (pinned to e1c734241f)
Solutions
- Make the subresource method return a concrete, indexed interface or class — not a wrapper type like Optional or a collection.
- Ensure the module containing the subresource type is indexed: add the jandex-maven-plugin (process goal) or a META-INF/jandex.idx to the dependency jar.
- If the type is in a third-party jar, add quarkus.index-dependency.<name>.group-id/artifact config entries so Quarkus indexes it.
- Restructure so the client method is a normal endpoint (returning response types) rather than a subresource locator.
Example fix
// before
@Path("/items")
Optional<ItemSubResource> getItems();
// after
@Path("/items")
ItemSubResource getItems(); Defensive patterns
Strategy: validation
Validate before calling
// Subresource locator methods must return a bare, concrete class/interface name
Method m = clientInterface.getMethod("getItems");
Type rt = m.getGenericReturnType();
if (rt instanceof ParameterizedType) {
throw new IllegalStateException("Subresource locator must not return a generic type: " + rt);
} Prevention
- Return plain interface/class types from subresource locator methods
- Index every dependency containing client types (jandex plugin or quarkus.index-dependency.*)
- Never wrap subresource return types in Optional/Collection
When it happens
Trigger: A REST Client interface method (a subresource locator) returns a type that is: a primitive, a generic/parameterized type not resolvable to a class, generated at runtime, or in a dependency not part of the Jandex index used during client build-step processing.
Common situations: Returning Optional<SubResource> or List<SubResource> from a locator method; subresource interface living in a jar without a Jandex index (missing jandex-maven-plugin processing); Quarkus version change altering which types get indexed.
Related errors
- Class ${className} used in ${annotationName} on ${declaringC
- REST client interface: " + clazz + " was not indexed at buil
- Failed to process ${path}
- Annotation instance ${annotationInstance} does not match ann
- The class is not inside the Jandex index
AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05).
Data as JSON: /api/errors/aabc6e20aed0b379.
Report an issue: GitHub.