quarkusio/quarkus · error · IllegalArgumentException

Not a REST client interface: " + clazz + ". No @Path annotat

Error message

Not a REST client interface: " + clazz + ". No @Path annotation found on the class or any methods of the interface and no HTTP method annotations (@POST, @PUT, @GET, @HEAD, @DELETE, etc) found on any of the methods

What it means

The requested class has no generated client proxy and carries no REST client annotations at all, so it cannot be a REST client interface. ClientProxies.get() falls through to this IllegalArgumentException when the interface lacks @Path on itself or its methods and lacks any HTTP method annotation (@GET, @POST, @PUT, @HEAD, @DELETE, etc.).

Source

Thrown at independent-projects/resteasy-reactive/client/runtime/src/main/java/org/jboss/resteasy/reactive/client/impl/ClientProxies.java:38

    public ClientProxies(Map<Class<?>, BiFunction<WebTarget, List<ParamConverterProvider>, ?>> clientProxies,
            Map<Class<?>, String> failures) {
        this.clientProxies = clientProxies;
        this.failures = failures;
    }

    public <T> T get(Class<?> clazz, WebTarget webTarget, List<ParamConverterProvider> providers) {
        BiFunction<WebTarget, List<ParamConverterProvider>, ?> function = clientProxies.get(clazz);
        if (function == null) {
            String failure = failures.get(clazz);
            if (failure != null) {
                throw new InvalidRestClientDefinitionException(
                        "Failed to generate client for class " + clazz + " : " + failure);
            } else {
                if (hasRestClientAnnotations(clazz)) {
                    throw new IllegalStateException("REST client interface: " + clazz
                            + " was not indexed at build time. See https://quarkus.io/guides/cdi-reference#bean_discovery for information on how to index the module that contains it.");
                } else {
                    throw new IllegalArgumentException("Not a REST client interface: " + clazz + ". No @Path annotation " +
                            "found on the class or any methods of the interface and no HTTP method annotations " +
                            "(@POST, @PUT, @GET, @HEAD, @DELETE, etc) found on any of the methods");
                }
            }
        }
        //noinspection unchecked
        return (T) function.apply(webTarget, providers);
    }

    private boolean hasRestClientAnnotations(Class<?> clazz) {
        for (Annotation annotation : clazz.getAnnotations()) {
            if (isRestClientAnnotation(annotation)) {
                return true;
            }
        }
        for (Method method : clazz.getDeclaredMethods()) {
            for (Annotation annotation : method.getDeclaredAnnotations()) {
                if (isRestClientAnnotation(annotation)) {

View on GitHub (pinned to e1c734241f)

Solutions

  1. Annotate the interface with @Path (class or method level) and each method with an HTTP method annotation (@GET/@POST/@PUT/@DELETE/@HEAD)
  2. Verify you are passing the actual REST client interface, not a DTO/model interface
  3. Add @RegisterRestClient if using MicroProfile REST client configuration
  4. Rebuild after adding annotations so the build-time proxy generation picks it up

Example fix

// before
public interface ItemClient { Item get(String id); }

// after
@Path("/items")
@RegisterRestClient
public interface ItemClient {
    @GET
    @Path("/{id}")
    Item get(@PathParam("id") String id);
}
Defensive patterns

Strategy: validation

Validate before calling

// verify the interface is a valid REST client before building
static boolean isRestClientInterface(Class<?> c) {
    if (!c.isInterface()) return false;
    if (c.isAnnotationPresent(jakarta.ws.rs.Path.class)) return true;
    for (Method m : c.getMethods()) {
        if (m.isAnnotationPresent(jakarta.ws.rs.Path.class)) return true;
        for (Annotation a : m.getAnnotations())
            if (a.annotationType().getName().startsWith("jakarta.ws.rs.")) return true;
    }
    return false;
}

Type guard

boolean isValidRestClient(Class<?> c) { return c.isInterface() && isRestClientInterface(c); }

Try / catch

try {
    return builder.build(clazz);
} catch (IllegalArgumentException e) {
    if (e.getMessage().startsWith("Not a REST client interface")) {
        throw new ConfigurationException("Register the annotated client interface, not " + clazz, e);
    }
    throw e;
}

Prevention

When it happens

Trigger: Passing a plain (unannotated) interface or class to QuarkusRestClientBuilder/ClientProxies.get() expecting a proxy to be created.

Common situations: Mistakenly registering the wrong interface (e.g. the API model class instead of the client); forgetting @Path or the @GET/@POST annotations on interface methods; refactor moved annotations off the interface; typos in package imports (wrong @Path).

Related errors


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