{"record":{"id":"671d13be7a114a14","repo":"apache/dolphinscheduler","slug":"cannot-find-service-servicename-from-service-def","errorCode":null,"errorMessage":"cannot find service <serviceName> from service definition","messagePattern":"cannot find service <serviceName> from service definition","errorType":"exception","errorClass":"GrpcParserException","httpStatus":null,"severity":"error","filePath":"dolphinscheduler-task-plugin/dolphinscheduler-task-grpc/src/main/java/org/apache/dolphinscheduler/plugin/task/grpc/protobufjs/GrpcDynamicService.java","lineNumber":57,"sourceCode":"import io.netty.channel.nio.NioEventLoopGroup;\nimport io.netty.channel.socket.nio.NioSocketChannel;\n\npublic class GrpcDynamicService {\n\n    Descriptors.FileDescriptor fileDescriptor;\n    ManagedChannel channel;\n\n    public GrpcDynamicService(ManagedChannel channel, Descriptors.FileDescriptor fileDesc) {\n        this.fileDescriptor = fileDesc;\n        this.channel = channel;\n    }\n\n    public DynamicMessage call(String methodNameWithService, String messageJSON, long timeout) {\n        MethodName methodNameData = new MethodName(methodNameWithService);\n        Descriptors.ServiceDescriptor pServiceDescriptor =\n                fileDescriptor.findServiceByName(methodNameData.getServiceName());\n        if (isNull(pServiceDescriptor))\n            throw new GrpcParserException(\n                    \"cannot find service <\" + methodNameData.getServiceName() + \"> from service definition\");\n        Descriptors.MethodDescriptor pMethodDescriptor =\n                pServiceDescriptor.findMethodByName(methodNameData.getRpcName());\n        if (isNull(pMethodDescriptor))\n            throw new GrpcParserException(\"cannot find method <\" + methodNameData.getRpcName() + \"> from service <\"\n                    + methodNameData.getServiceName() + \"> with method list: \" + Arrays.toString(pServiceDescriptor\n                            .getMethods().stream().map(Descriptors.MethodDescriptor::getName).toArray()));\n        MethodDescriptor<DynamicMessage, DynamicMessage> methodDescriptor =\n                methodFromProtobuf(pServiceDescriptor, pMethodDescriptor);\n        Descriptors.Descriptor requestMessageType = pMethodDescriptor.getInputType();\n        Descriptors.Descriptor responseMessageType = pMethodDescriptor.getOutputType();\n        DynamicMessage.Builder requestBuilder = DynamicMessage.newBuilder(requestMessageType);\n        DynamicMessage.Builder responseBuilder = DynamicMessage.newBuilder(responseMessageType);\n        try {\n            JsonFormat.parser().ignoringUnknownFields().merge(messageJSON, requestBuilder);\n        } catch (InvalidProtocolBufferException ipbe) {\n            throw new GrpcParserException(\n                    \"cannot merge json message to protobuf definition type <\" + requestMessageType.getName() + \">\",","sourceCodeStart":39,"sourceCodeEnd":75,"githubUrl":"https://github.com/apache/dolphinscheduler/blob/02eac45a1b6676e639fcbfb4be2243de5771b05d/dolphinscheduler-task-plugin/dolphinscheduler-task-grpc/src/main/java/org/apache/dolphinscheduler/plugin/task/grpc/protobufjs/GrpcDynamicService.java#L39-L75","documentation":"GrpcDynamicService.call() parses a 'ServiceName.rpcName' string, then looks up the service in the parsed proto FileDescriptor via findServiceByName(). When no service with that name exists in the loaded .proto definition, it throws GrpcParserException. This means the service part of the method string does not match any service declared in the proto file the task compiled.","triggerScenarios":"Calling GrpcDynamicService.call() with a methodNameWithService whose service name is misspelled, uses the wrong case, or refers to a service not declared in the .proto file loaded into fileDescriptor.","commonSituations":"Typo or wrong casing in the task's 'method' config field; the proto file was updated/renamed and the config still references the old service name; the wrong .proto file was configured so the target service lives in a different descriptor; nested/packaged service names where only the simple name is expected.","solutions":["Check the service name in the methodNameWithService string ('Service.rpc') against the 'service X {...}' declarations in your .proto file and fix spelling/casing.","Verify the task is configured with the .proto file that actually declares that service (proto file path config).","List available services by iterating fileDescriptor.getServices() and use the exact getName() value.","If the proto file changed, update the config to the new service name and re-run."],"exampleFix":"// before\ngrpcTask.call(\"UserService.getUser\", json, 3000); // proto declares 'UserSvc'\n// after\ngrpcTask.call(\"UserSvc.getUser\", json, 3000);","handlingStrategy":"validation","validationCode":"boolean serviceExists = java.util.Arrays.stream(fileDescriptor.getServices())\n    .anyMatch(s -> s.getName().equals(serviceName));\nif (!serviceExists) {\n    throw new IllegalArgumentException(\"Unknown service \" + serviceName + \"; available: \"\n        + java.util.Arrays.toString(fileDescriptor.getServices().stream()\n            .map(s -> s.getName()).toArray()));\n}","typeGuard":null,"tryCatchPattern":"try {\n    dynamicService.call(methodNameWithService, json, timeout);\n} catch (GrpcParserException e) {\n    if (e.getMessage().contains(\"cannot find service\")) {\n        // log available services and fail fast with a corrected method string\n    }\n    throw e;\n}","preventionTips":["Keep the method string ('Service.rpc') in config synchronized with the .proto file and validate on task startup.","Check service name spelling and casing against the 'service X' declaration in the .proto.","Log the available service names (fileDescriptor.getServices()) when config validation fails."],"tags":["grpc","protobuf","service-not-found","configuration"],"backgroundTag":"resource-not-found","analyzedSha":"02eac45a1b6676e639fcbfb4be2243de5771b05d","analyzedAt":"2026-09-06T17:43:00.555Z","contentChangedAt":"2026-09-06T17:43:00.555Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}