{"record":{"id":"e3637a45c7b793ec","repo":"apache/hadoop","slug":"unknown-method-called-on-protocol","errorCode":null,"errorMessage":"Unknown method {} called on {} protocol.","messagePattern":"Unknown method (.+?) called on (.+?) protocol\\.","errorType":"exception","errorClass":"RpcNoSuchMethodException","httpStatus":null,"severity":"error","filePath":"hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/ipc/ProtobufRpcEngine.java","lineNumber":483,"sourceCode":"    }\n\n    /**\n     * This implementation is same as\n     * ProtobufRpcEngine2.Server.ProtobufInvoker#call(..)\n     * except this implementation uses non-shaded protobuf classes from legacy\n     * protobuf version (default 2.5.0).\n     */\n    static RpcWritable processCall(RPC.Server server,\n        String connectionProtocolName, RpcWritable.Buffer request,\n        String methodName, ProtoClassProtoImpl protocolImpl) throws Exception {\n      BlockingService service = (BlockingService) protocolImpl.protocolImpl;\n      MethodDescriptor methodDescriptor = service.getDescriptorForType()\n          .findMethodByName(methodName);\n      if (methodDescriptor == null) {\n        String msg = \"Unknown method \" + methodName + \" called on \"\n                              + connectionProtocolName + \" protocol.\";\n        LOG.warn(msg);\n        throw new RpcNoSuchMethodException(msg);\n      }\n      Message prototype = service.getRequestPrototype(methodDescriptor);\n      Message param = request.getValue(prototype);\n\n      Message result;\n      Call currentCall = Server.getCurCall().get();\n      try {\n        server.rpcDetailedMetrics.init(protocolImpl.protocolClass);\n        CURRENT_CALL_INFO.set(new CallInfo(server, methodName));\n        currentCall.setDetailedMetricsName(methodName);\n        result = service.callBlockingMethod(methodDescriptor, null, param);\n        // Check if this needs to be a deferred response,\n        // by checking the ThreadLocal callback being set\n        if (currentCallback.get() != null) {\n          currentCall.deferResponse();\n          currentCallback.set(null);\n          return null;\n        }","sourceCodeStart":465,"sourceCodeEnd":501,"githubUrl":"https://github.com/apache/hadoop/blob/2add9630210752f88ceb1bb74eb65e37bf41da8e/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/ipc/ProtobufRpcEngine.java#L465-L501","documentation":"Server-side: processCall looks up the client-requested methodName in the protobuf BlockingService's descriptor; an unknown name logs a warning and throws RpcNoSuchMethodException, which travels back to the client as a RemoteException. It means the connection and protocol handshake succeeded but the server's version of the protocol has no such RPC — classically a client/server version skew or a hand-crafted call with a typo.","triggerScenarios":"A newer client calls an RPC method added after the running server's version (e.g., new HDFS API used against an older NameNode); a method removed/renamed across protocol versions; reflective or manual RPC clients sending a wrong method-name string.","commonSituations":"Rolling upgrades where applications run new client jars against old daemons; mixing Hadoop minor versions in tooling; custom protobuf protocols after a rename without bumping protocol version; tools probing servers for capability by calling methods speculatively.","solutions":["Align versions: run client jars matching the server's Hadoop version (or rely on the protobuf protocol's compatibility guarantees).","If probing for capability, catch RemoteException whose cause is RpcNoSuchMethodException and fall back to the older API.","For custom protocols, bump the protocol versionID when methods change so VersionMismatch surfaces instead."],"exampleFix":"// before\ntry {\n  response = proxy.newMethodAddedInHadoop3(req);\n} catch (RemoteException e) {\n  throw e; // crashes on older NameNode: Unknown method newMethodAddedInHadoop3\n}\n\n// after\ntry {\n  response = proxy.newMethodAddedInHadoop3(req);\n} catch (RemoteException e) {\n  if (e.getErrorCode().equals(RpcNoSuchMethodException.class.getName())) {\n    response = legacyFallbackPath(req); // capability probe pattern\n  } else { throw e; }\n}","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n  return proxy.maybeNewMethod(req);\n} catch (RemoteException e) {\n  if (RpcNoSuchMethodException.class.getName().equals(e.getErrorCode())) {\n    return legacyFallback(req); // server version lacks the method\n  }\n  throw e;\n}","preventionTips":["Pin client/server Hadoop versions; during rolling upgrades probe capabilities with the catch pattern above.","For custom protobuf protocols bump versionID on incompatible changes so mismatches fail at handshake.","Log the server version at client connect and compare before calling new APIs."],"tags":["hadoop","ipc","rpc","protobuf","version-mismatch","server"],"backgroundTag":"rpc-version-mismatch","analyzedSha":"2add9630210752f88ceb1bb74eb65e37bf41da8e","analyzedAt":"2026-08-22T19:55:07.957Z","schemaVersion":2},"datasetVersion":"2026-08-22T20:17:22.307Z"}