quarkusio/quarkus · error · IllegalStateException
A gRPC service injection is missing the @GrpcClient qualifie
Error message
A gRPC service injection is missing the @GrpcClient qualifier: ${class}#${field} What it means
A field of a gRPC service interface type is annotated only with @Inject (no @GrpcClient qualifier). Quarkus-generated clients require @GrpcClient to disambiguate which configured client/service to inject; an unqualified injection cannot be resolved, so deployment fails.
Source
Thrown at extensions/grpc/deployment/src/main/java/io/quarkus/grpc/deployment/GrpcClientProcessor.java:321
}
@BuildStep
public void validateInjectedServiceInterfaces(CombinedIndexBuildItem index,
// Dummy producer - this build step needs to be executed before the CDI container is initialized
BuildProducer<UnremovableBeanBuildItem> dummy) {
// Attempt to detect wrong service interface injection points
// Note that we cannot use injection points metadata because the build can fail with unsatisfied dependency before
Set<DotName> serviceInterfaces = new HashSet<>();
for (ClassInfo serviceInterface : index.getIndex().getKnownDirectImplementors(GrpcDotNames.MUTINY_SERVICE)) {
serviceInterfaces.add(serviceInterface.name());
}
for (AnnotationInstance injectAnnotation : index.getIndex().getAnnotations(DotNames.INJECT)) {
if (injectAnnotation.target().kind() == Kind.FIELD) {
FieldInfo field = injectAnnotation.target().asField();
if (serviceInterfaces.contains(field.type().name()) && field.annotations().size() == 1) {
// e.g. @Inject Greeter
throw new IllegalStateException("A gRPC service injection is missing the @GrpcClient qualifier: "
+ field.declaringClass().name() + "#" + field.name());
}
} else if (injectAnnotation.target().kind() == Kind.METHOD) {
// CDI initializer
MethodInfo method = injectAnnotation.target().asMethod();
short position = 0;
for (Type param : method.parameterTypes()) {
position++;
if (serviceInterfaces.contains(param.name())) {
// e.g. @Inject void setGreeter(Greeter greeter)
Set<AnnotationInstance> annotations = new HashSet<>();
for (AnnotationInstance annotation : method.annotations()) {
if (annotation.target().kind() == Kind.METHOD_PARAMETER
&& annotation.target().asMethodParameter().position() == position) {
annotations.add(annotation);
}
}
if (annotations.size() > 1) {View on GitHub (pinned to e1c734241f)
Solutions
- Add the @GrpcClient qualifier: @Inject @GrpcClient("hello-service") Greeter greeter;
- If using the generated Mutiny bean, still add @GrpcClient to name/qualify the client
- Check all @Inject fields typed as .proto service interfaces
Example fix
// before
@Inject Greeter greeter;
// after
@Inject @GrpcClient("hello-service") Greeter greeter; Defensive patterns
Strategy: validation
Validate before calling
// every gRPC service injection needs the qualifier
@Inject @GrpcClient("hello-service") Greeter greeter; // correct pattern to copy Prevention
- Always pair @Inject with @GrpcClient for .proto service interface fields
- Grep for @Inject on service-interface types during code review
- Add an ArchUnit/checkstyle rule if the mistake recurs
When it happens
Trigger: A field whose type is a known gRPC service interface has exactly one annotation (@Inject) and no @GrpcClient, e.g. @Inject Greeter greeter; during validateInjectedServiceInterfaces.
Common situations: Following generic CDI examples that omit qualifiers; migrating from other gRPC frameworks; IDE auto-completing @Inject only; removing @GrpcClient during cleanup.
Related errors
- A gRPC service injection is missing the @GrpcClient qualifie
- Unable to derive the service interface for the generated Mut
- Unable to determine the client name from the parameter at po
- ${clientAnnotation} may not be declared at ${target}
- Invalid @GrpcClient `${targetInfo}` - client name cannot be
AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05).
Data as JSON: /api/errors/d3dea496bf57dfb6.
Report an issue: GitHub.