apache/druid · error · QueryDriver.RequestError
The Protobuf class [%s] is not known. Is your protobuf jar o
Error message
The Protobuf class [%s] is not known. Is your protobuf jar on the class path?
What it means
When the request specifies a protobuf message name for results, getProtobufClass loads it with Class.forName. If the named class is absent from the server's class path, a ClassNotFoundException is wrapped in RequestError("The Protobuf class [%s] is not known. Is your protobuf jar on the class path?"). The server cannot construct the response message type the client asked for.
Source
Thrown at extensions-contrib/grpc-query/src/main/java/org/apache/druid/grpc/server/QueryDriver.java:758
skipColumns
);
break;
default:
throw new RequestError("Unsupported query result format: " + request.getResultFormat());
}
GrpcResultsAccumulator accumulator = new GrpcResultsAccumulator(writer);
accumulator.push(result);
return ByteString.copyFrom(out.toByteArray());
}
@SuppressWarnings("unchecked")
private Class<GeneratedMessage> getProtobufClass(final QueryRequest request)
{
try {
return (Class<GeneratedMessage>) Class.forName(request.getProtobufMessageName());
}
catch (ClassNotFoundException e) {
throw new RequestError(
"The Protobuf class [%s] is not known. Is your protobuf jar on the class path?",
request.getProtobufMessageName()
);
}
catch (ClassCastException e) {
throw new RequestError(
"The class [%s] is not a Protobuf",
request.getProtobufMessageName()
);
}
}
}
View on GitHub (pinned to 9b90983fd2)
Solutions
- Verify request.getProtobufMessageName() is the exact fully-qualified class name of a GeneratedMessage subclass (e.g. com.acme.FooResponse).
- Deploy the jar containing the generated protobuf class to the server's class path (extensions directory or lib).
- Regenerate the client's message name from the same .proto the server uses; check for package relocation changes.
- Log/print the requested name server-side and confirm with `jar tf` that the class exists in the deployed artifacts.
Example fix
// before
request.setProtobufMessageName("com.acme.old.Result");
// after
request.setProtobufMessageName("com.acme.v2.ResultRow"); // matches deployed jar Defensive patterns
Strategy: validation
Validate before calling
// Check the class is loadable before sending the request
try {
Class.forName(protobufMessageName);
} catch (ClassNotFoundException e) {
throw new IllegalStateException("protobuf class not on server class path: " + protobufMessageName, e);
} Type guard
boolean isKnownProtobuf(String name) {
try {
return GeneratedMessage.class.isAssignableFrom(Class.forName(name));
} catch (Throwable t) {
return false;
}
} Try / catch
try {
return stub.query(req);
} catch (StatusRuntimeException e) {
if (String.valueOf(e.getStatus().getDescription()).contains("is not known")) {
throw new IllegalStateException("deploy the jar containing " + req.getProtobufMessageName() + " to the server", e);
}
throw e;
} Prevention
- Copy-paste the FQCN from the generated class rather than typing it.
- Ensure the jar with generated protobuf classes is bundled with the server extension.
- Generate the protobufMessageName from the same compiled .proto used by the server.
- Add a startup check that resolves configured message names via Class.forName.
When it happens
Trigger: QueryRequest.protobufMessageName is set to a class name (FQCN) that is not loadable in the gRPC server's JVM — misspelled FQCN, class from a jar not shipped to the server, or proto package renamed in a version upgrade.
Common situations: Client and server generated protobuf classes differ (package/name changed between proto versions); the custom message jar was never deployed to the Druid extension directory; typo in the message name; shade/relocation changed the class package.
Related errors
- The class [%s] is not a Protobuf
- Invalid parameter type:
- Unauthorized
- Unsupported query result format:
- The gRPC query server requires either a Basic or Anonymous a
AI-assisted analysis of apache/druid@9b90983fd2 (2026-09-07).
Data as JSON: /api/errors/599921a064adb540.
Report an issue: GitHub.