quarkusio/quarkus · error · IllegalStateException

@RegisterClientContextResolver is only supported on static m

Error message

@RegisterClientContextResolver is only supported on static methods of REST Client interfaces that return an object. Offending instance is '${className}#${methodName}'

What it means

When scanning a REST client interface for @RegisterClientContextResolver methods, Quarkus requires the annotated static method to return an object (it is invoked to produce a context resolver instance/value). A void static method cannot supply anything, so the build fails with this IllegalStateException.

Source

Thrown at extensions/resteasy-reactive/rest-client/deployment/src/main/java/io/quarkus/rest/client/reactive/deployment/ClientContextResolverHandler.java:147

                            targetMethodParams.values().toArray(new Expr[0]));
                    bc.return_(resultHandle);
                });
            });
        });

        return new GeneratedClassResult(restClientInterfaceClassInfo.name().toString(), generatedClassName, priority);
    }

    private MethodInfo findTargetMethod(AnnotationInstance instance) {
        MethodInfo targetMethod = null;
        if (instance.target().kind() == AnnotationTarget.Kind.METHOD) {
            targetMethod = instance.target().asMethod();
            if (ignoreAnnotation(targetMethod)) {
                return null;
            }
            if ((targetMethod.flags() & Modifier.STATIC) != 0) {
                if (targetMethod.returnType().kind() == Type.Kind.VOID) {
                    throw new IllegalStateException(annotation
                            + " is only supported on static methods of REST Client interfaces that return an object."
                            + " Offending instance is '" + targetMethod.declaringClass().name().toString() + "#"
                            + targetMethod.name() + "'");
                }

            }
        }

        return targetMethod;
    }

    private static Class<?> lookupReturnClass(MethodInfo targetMethod) {
        Class<?> returnTypeClassName = null;
        try {
            returnTypeClassName = Class.forName(targetMethod.returnType().name().toString(), false,
                    Thread.currentThread().getContextClassLoader());
        } catch (ClassNotFoundException ignored) {

View on GitHub (pinned to e1c734241f)

Solutions

  1. Give the annotated method a non-void return type matching the expected context resolver type
  2. Remove the @RegisterClientContextResolver annotation if the method is not meant to produce a resolver
  3. Move initialization side effects out of the client interface into an extension build step

Example fix

// before
@RegisterClientContextResolver
static void setup() { ... } // void not allowed
// after
@RegisterClientContextResolver
static MyResolver setup() { return new MyResolver(); }
Defensive patterns

Strategy: validation

Validate before calling

if (Modifier.isStatic(m.getModifiers()) && m.getReturnType() == void.class) {
    throw new IllegalStateException("@RegisterClientContextResolver method must not be void");
}

Try / catch

try {
    handler.findTargetMethod(instance);
} catch (IllegalStateException e) {
    if (e.getMessage().contains("return an object")) { /* fix method signature */ }
    throw e;
}

Prevention

When it happens

Trigger: Annotating a static void method in a REST client interface with @RegisterClientContextResolver (annotation instance target resolves to a VOID-returning method).

Common situations: Method originally used for side-effectful registration refactored to return nothing; developer assumed annotation works like a marker; auto-generated interface where a method was emptied.

Related errors


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