quarkusio/quarkus · error · IllegalStateException
${clientAnnotation} may not be declared at ${target}
Error message
${clientAnnotation} may not be declared at ${target} What it means
@GrpcClient is only allowed on fields and method parameters (@Target({FIELD, PARAMETER})). If the annotation instance is found on any other target (class, method, etc.), the deployment throws this IllegalStateException. This is a defensive check that should be unreachable in normal Java code.
Source
Thrown at extensions/grpc/deployment/src/main/java/io/quarkus/grpc/deployment/GrpcClientProcessor.java:174
String clientName;
AnnotationValue clientNameValue = clientAnnotation.value();
if (clientNameValue == null || clientNameValue.asString().equals(GrpcClient.ELEMENT_NAME)) {
// Determine the service name from the annotated element
if (clientAnnotation.target().kind() == Kind.FIELD) {
clientName = clientAnnotation.target().asField().name();
} else if (clientAnnotation.target().kind() == Kind.METHOD_PARAMETER) {
MethodParameterInfo param = clientAnnotation.target().asMethodParameter();
clientName = param.method().parameterName(param.position());
if (clientName == null) {
throw new DeploymentException("Unable to determine the client name from the parameter at position "
+ param.position()
+ " in method "
+ param.method().declaringClass().name() + "#" + param.method().name()
+ "() - compile the class with debug info enabled (-g) or parameter names recorded (-parameters), or use GrpcClient#value() to specify the service name");
}
} else {
// This should never happen because @GrpcClient has @Target({ FIELD, PARAMETER })
throw new IllegalStateException(clientAnnotation + " may not be declared at " + clientAnnotation.target());
}
} else {
clientName = clientNameValue.asString();
}
if (clientName.trim().isEmpty()) {
throw new DeploymentException(
"Invalid @GrpcClient `" + injectionPoint.getTargetInfo() + "` - client name cannot be empty");
}
GrpcClientBuildItem item;
if (items.containsKey(clientName)) {
item = items.get(clientName);
} else {
item = new GrpcClientBuildItem(clientName);
items.put(clientName, item);
}
View on GitHub (pinned to e1c734241f)
Solutions
- Move @GrpcClient onto a field or a method parameter
- If generated by a tool, fix the generator to respect @GrpcClient's @Target
- Ensure no custom annotation transformer re-targets @GrpcClient
Example fix
// before
@GrpcClient("svc")
public class MyService { ... }
// after
public class MyService {
@Inject @GrpcClient("svc") Greeter greeter;
} Defensive patterns
Strategy: validation
Validate before calling
// only place @GrpcClient on fields or method parameters
@Target({ElementType.FIELD, ElementType.PARAMETER}) // existing definition — respect it
class MyBean { @Inject @GrpcClient("svc") Greeter greeter; } Prevention
- Check @Target of an annotation before applying it
- Never apply @GrpcClient at class or method level
When it happens
Trigger: An @GrpcClient annotation instance whose reflection target is neither a field nor a method parameter is processed during injection-point discovery — practically only via bytecode-generated/transformed classes or exotic annotation processing.
Common situations: Code-generation or bytecode tooling that misplaced the annotation; custom CDI extensions registering synthetic annotated members; manually built annotation instances in build steps.
Related errors
- Unable to derive the service interface for the generated Mut
- Unable to determine the client name from the parameter at po
- Invalid @GrpcClient `${targetInfo}` - client name cannot be
- A gRPC service injection is missing the @GrpcClient qualifie
- A gRPC service injection is missing the @GrpcClient qualifie
AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05).
Data as JSON: /api/errors/aee1cefeb5a5f167.
Report an issue: GitHub.