quarkusio/quarkus · error · IllegalStateException
The original implementation class of a gRPC service not foun
Error message
The original implementation class of a gRPC service not found: ${originalImplName} What it means
During Quarkus gRPC Dev UI processing, the build index is searched for the original (non-Mutiny) generated gRPC base class that corresponds to each Mutiny-generated service class. The Mutiny class name (e.g. examples.MutinyGreeterGrpc) is transformed by stripping the 'Mutiny' prefix, and the resulting class must exist in the Jandex index. If it does not, the deployment build fails with this IllegalStateException.
Source
Thrown at extensions/grpc/deployment/src/main/java/io/quarkus/grpc/deployment/devui/GrpcDevUIProcessor.java:245
return null;
}
@BuildStep(onlyIf = IsLocalDevelopment.class)
JsonRPCProvidersBuildItem createJsonRPCServiceForCache() {
return new JsonRPCProvidersBuildItem(GrpcJsonRPCService.class);
}
private Collection<Class<?>> getGrpcServices(IndexView index) throws ClassNotFoundException {
ClassLoader tccl = Thread.currentThread().getContextClassLoader();
Set<String> serviceClassNames = new HashSet<>();
for (ClassInfo mutinyGrpc : index.getAllKnownImplementors(GrpcDotNames.MUTINY_GRPC)) {
// Find the original impl class
// e.g. examples.MutinyGreeterGrpc -> examples.GreeterGrpc
DotName originalImplName = DotName
.createSimple(mutinyGrpc.name().toString().replace(MutinyGrpcGenerator.CLASS_PREFIX, ""));
ClassInfo originalImpl = index.getClassByName(originalImplName);
if (originalImpl == null) {
throw new IllegalStateException(
"The original implementation class of a gRPC service not found:" + originalImplName);
}
// Must declare static io.grpc.ServiceDescriptor getServiceDescriptor()
MethodInfo getServiceDescriptor = originalImpl.method("getServiceDescriptor");
if (getServiceDescriptor != null && Modifier.isStatic(getServiceDescriptor.flags())
&& getServiceDescriptor.returnType().name().toString().equals(ServiceDescriptor.class.getName())) {
serviceClassNames.add(getServiceDescriptor.declaringClass().name().toString());
}
}
serviceClassNames.add(HealthGrpc.class.getName());
DevConsoleManager.setGlobal("io.quarkus.grpc.serviceClassNames", serviceClassNames);
List<Class<?>> serviceClasses = new ArrayList<>();
for (String className : serviceClassNames) {
serviceClasses.add(tccl.loadClass(className));
}
return serviceClasses;View on GitHub (pinned to e1c734241f)
Solutions
- Ensure the base (non-Mutiny) gRPC service classes are generated: keep the default quarkus.generate-code.grpc settings so both <Name>Grpc and Mutiny<Name>Grpc are produced.
- If stubs are pre-generated and committed, make sure the base *Grpc classes are on the application classpath (not just the Mutiny ones) so Jandex can index them.
- Check that generated sources are included in indexing (they normally are inside the same module); avoid exclude patterns in quarkus.index-dependency or jandex config that drop the generated package.
- Rebuild cleanly (mvn clean install) so code generation re-runs and both classes are regenerated consistently.
Example fix
// before (pom.xml disables base class generation) <plugin>org.xolstice.maven.plugins:protobuf-maven-plugin ... only mutiny generation</plugin> // after Remove custom exclusions and let quarkus-maven-plugin generate both: <Name>Grpc.java and Mutiny<Name>Grpc.java in the same package
Defensive patterns
Strategy: validation
Validate before calling
// in a deployment test or startup check
DotName impl = DotName.createSimple(mutinyName.replace("Mutiny", ""));
if (index.getClassByName(impl) == null) {
throw new IllegalStateException("Missing generated base class: " + impl + "; check gRPC code-gen config");
} Try / catch
try {
processServices();
} catch (IllegalStateException e) {
if (e.getMessage().startsWith("The original implementation class of a gRPC service not found")) {
// fix code-gen config or add missing generated sources, then rebuild
} else throw e;
} Prevention
- Keep default quarkus gRPC code-gen settings so both base and Mutiny classes are generated
- Never commit only Mutiny*Grpc stubs without the base *Grpc classes
- Avoid jandex/index exclude patterns covering generated packages
- Run mvn clean after changing proto files or generator options
When it happens
Trigger: A proto file produces Mutiny<Name>Grpc classes but the base <Name>Grpc class is missing from the index — e.g. quarkus-grpc code-gen is configured with generate-code non-mutiny disabled, the base generated class was excluded from indexing, or a custom protoc plugin setup generates only the Mutiny variant.
Common situations: Custom gRPC code generation configs that disable base class generation; mixing pre-generated stubs (only Mutiny classes committed) with Quarkus indexing; upgrading Quarkus and changing quarkus.generate-code.grpc options.
Related errors
- Invalid type:
- Injected class not found in index:
- Code generation failed. Please check the log above for detai
- Couldn't find id field of ${classInfo}
- Custom JDBC delegate implementation class '%s' was not found
AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05).
Data as JSON: /api/errors/e42b3e7a1edd303a.
Report an issue: GitHub.