quarkusio/quarkus · error · IllegalStateException
@ClientRedirectHandler is only supported on static methods o
Error message
@ClientRedirectHandler is only supported on static methods of REST Client interfaces that take 'jakarta.ws.rs.core.Response' as a single parameter and return 'java.net.URI'. Offending instance is '${className}#${methodName}' What it means
@ClientRedirectHandler annotates a static method that decides a redirect URI from a failed Response. Quarkus enforces the exact contract: static method, single jakarta.ws.rs.core.Response parameter, java.net.URI return type. This IllegalStateException fails the build when the annotated method violates it.
Source
Thrown at extensions/resteasy-reactive/rest-client/deployment/src/main/java/io/quarkus/rest/client/reactive/deployment/ClientRedirectHandler.java:87
boolean returnsUri = URI.class.isAssignableFrom(
Class.forName(returnTypeClassName, false, Thread.currentThread().getContextClassLoader()));
if (returnsUri) {
isValid = true;
}
} catch (ClassNotFoundException ignored) {
}
}
}
if (!isValid) {
String message = DotNames.CLIENT_REDIRECT_HANDLER
+ " is only supported on static methods of REST Client interfaces that take 'jakarta.ws.rs.core.Response'"
+ " as a single parameter and return 'java.net.URI'.";
if (targetMethod != null) {
message += " Offending instance is '" + targetMethod.declaringClass().name().toString() + "#"
+ targetMethod.name() + "'";
}
throw new IllegalStateException(message);
}
StringBuilder sigBuilder = new StringBuilder();
sigBuilder.append(targetMethod.name()).append("_").append(targetMethod.returnType().name().toString());
for (Type i : targetMethod.parameterTypes()) {
sigBuilder.append(i.name().toString());
}
int priority = Priorities.USER;
AnnotationValue priorityAnnotationValue = instance.value("priority");
if (priorityAnnotationValue != null) {
priority = priorityAnnotationValue.asInt();
}
ClassInfo restClientInterfaceClassInfo = targetMethod.declaringClass();
String generatedClassName = restClientInterfaceClassInfo.name().toString() + "_" + targetMethod.name() + "_"
+ "ResponseRedirectHandler" + "_" + HashUtil.sha1(sigBuilder.toString());
final MethodInfo target = targetMethod;View on GitHub (pinned to e1c734241f)
Solutions
- Change the method to accept exactly one jakarta.ws.rs.core.Response and return java.net.URI
- Make the method static and keep it in the REST client interface
- Convert String URLs with URI.create(...) before returning
Example fix
// before
@ClientRedirectHandler
static String redirect(Response r) { return "/login"; }
// after
@ClientRedirectHandler
static java.net.URI redirect(Response r) {
return java.net.URI.create("/login");
} Defensive patterns
Strategy: validation
Validate before calling
static boolean validRedirectHandler(Method m) {
return Modifier.isStatic(m.getModifiers())
&& m.getParameterCount() == 1
&& m.getParameterTypes()[0] == jakarta.ws.rs.core.Response.class
&& m.getReturnType() == java.net.URI.class;
} Try / catch
try {
handler.generateResponseExceptionMapper(classResult, instance);
} catch (IllegalStateException e) {
if (e.getMessage().contains("ClientRedirectHandler")) { /* fix to (Response)->URI */ }
throw e;
} Prevention
- Use exact signature: static java.net.URI name(jakarta.ws.rs.core.Response r)
- Convert String URLs with URI.create(...) inside the method
- Do not add extra parameters for context
When it happens
Trigger: @ClientRedirectHandler method that is non-static, has no or extra parameters, does not take Response, or returns String/void/other instead of java.net.URI.
Common situations: Returning a String URL instead of URI; adding a second parameter for context; copy-pasting an @ClientExceptionMapper method and changing only the annotation.
Related errors
- Only a single instance of '@ClientRedirectHandler' with the
- @RegisterClientContextResolver is only supported on static m
- @RegisterClientContextResolver is only supported on static m
- @ClientExceptionMapper is only supported on static methods o
- Classes used in @SseEventFilter must have a no-args construc
AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05).
Data as JSON: /api/errors/04f1b6381c4b37de.
Report an issue: GitHub.