quarkusio/quarkus · error · IllegalStateException
Unable to derive the service interface for the generated Mut
Error message
Unable to derive the service interface for the generated Mutiny client: ${generatedClient} What it means
During gRPC client generation, Quarkus scans the @GrpcClient-annotated injection point's type for the @MutinyClient annotation to determine which service interface the generated Mutiny client implements. If the generated client class carries no annotation other than @MutinyClient (so no service interface can be derived), the deployment fails. This usually means the class being injected is not a properly generated Mutiny gRPC client.
Source
Thrown at extensions/grpc/deployment/src/main/java/io/quarkus/grpc/deployment/GrpcClientProcessor.java:143
void discoverInjectedClients(BeanDiscoveryFinishedBuildItem beanDiscovery,
BuildProducer<GrpcClientBuildItem> clients,
CombinedIndexBuildItem index) {
Map<String, GrpcClientBuildItem> items = new HashMap<>();
// Collect a map of service interface name to the generated client class
Map<DotName, DotName> generatedClients = new HashMap<>();
for (ClassInfo generatedClient : index.getIndex().getKnownDirectImplementors(GrpcDotNames.MUTINY_CLIENT)) {
// Mutiny client implements MutinyClient and the service interface
DotName serviceInterface = null;
for (DotName name : generatedClient.interfaceNames()) {
if (!name.equals(GrpcDotNames.MUTINY_CLIENT)) {
serviceInterface = name;
break;
}
}
if (serviceInterface == null) {
throw new IllegalStateException(
"Unable to derive the service interface for the generated Mutiny client: " + generatedClient);
}
generatedClients.put(serviceInterface, generatedClient.name());
}
for (InjectionPointInfo injectionPoint : beanDiscovery.getInjectionPoints()) {
AnnotationInstance clientAnnotation = injectionPoint.getRequiredQualifier(GrpcDotNames.GRPC_CLIENT);
if (clientAnnotation == null) {
continue;
}
Set<String> registeredInterceptors = getRegisteredInterceptors(injectionPoint);
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();View on GitHub (pinned to e1c734241f)
Solutions
- Inject the generated Mutiny service interface (e.g. Greeter from the .proto, or use @GrpcClient with the named client) instead of a custom class
- Verify the stubs are generated by Quarkus's protobuf codegen (mvn compile) and the class actually has both @MutinyClient and the service interface annotation
- Check that the @GrpcClient value or annotated type matches a service defined in your .proto files
- Clean and rebuild so generated sources are up to date
Example fix
// before
@Inject @GrpcClient MyCustomClient client;
// after
@Inject @GrpcClient("hello-service") Greeter greeter; Defensive patterns
Strategy: validation
Validate before calling
// before injecting, check the type maps to a generated Mutiny client service interface
if (!(client instanceof io.quarkus.grpc.runtime.MutinyGrpc) && !isGeneratedMutinyClient(client.getClass())) {
throw new IllegalArgumentException("Use the generated service interface, not " + client.getClass());
} Type guard
static boolean isGeneratedMutinyClient(Class<?> c) {
return c != null && java.util.Arrays.stream(c.getAnnotations())
.anyMatch(a -> a.annotationType().getName().endsWith("MutinyClient"));
} Prevention
- Always inject the interface generated from your .proto, not hand-written classes
- Run ./mvnw clean compile so generated sources exist before coding against them
- Keep the Quarkus gRPC codegen plugin version aligned with your Quarkus BOM
When it happens
Trigger: A bean declares @Inject @GrpcClient SomeClient where SomeClient is annotated with @MutinyClient but no additional annotation naming the service interface; i.e. the type cannot be mapped back to a gRPC service interface during discoverInjectedClients.
Common situations: Hand-written classes annotated with @MutinyClient by mistake; injection of the wrong generated type after regenerating stubs; upgrading Quarkus or the gRPC code generator so the generated client no longer carries the expected service-interface annotation; copy-pasting a client class name that does not exist in the generated sources.
Related errors
- 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
- 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/1c180f0e54d5c2e6.
Report an issue: GitHub.