{"record":{"id":"c62d1f00a9ced34b","repo":"apache/hadoop","slug":"unknown-protocol","errorCode":null,"errorMessage":"Unknown protocol: {}","messagePattern":"Unknown protocol: (.+?)","errorType":"exception","errorClass":"RpcNoSuchProtocolException","httpStatus":null,"severity":"error","filePath":"hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/ipc/ProtobufRpcEngine2.java","lineNumber":529,"sourceCode":"        return RPC_INVOKER;\n      }\n      return super.getServerRpcInvoker(rpcKind);\n    }\n\n    /**\n     * Protobuf invoker for {@link RpcInvoker}.\n     */\n    static class ProtoBufRpcInvoker implements RpcInvoker {\n      private static ProtoClassProtoImpl getProtocolImpl(RPC.Server server,\n          String protoName, long clientVersion) throws RpcServerException {\n        ProtoNameVer pv = new ProtoNameVer(protoName, clientVersion);\n        ProtoClassProtoImpl impl =\n            server.getProtocolImplMap(RPC.RpcKind.RPC_PROTOCOL_BUFFER).get(pv);\n        if (impl == null) { // no match for Protocol AND Version\n          VerProtocolImpl highest = server.getHighestSupportedProtocol(\n              RPC.RpcKind.RPC_PROTOCOL_BUFFER, protoName);\n          if (highest == null) {\n            throw new RpcNoSuchProtocolException(\n                \"Unknown protocol: \" + protoName);\n          }\n          // protocol supported but not the version that client wants\n          throw new RPC.VersionMismatch(protoName, clientVersion,\n              highest.version);\n        }\n        return impl;\n      }\n\n      @Override\n      /**\n       * This is a server side method, which is invoked over RPC. On success\n       * the return response has protobuf response payload. On failure, the\n       * exception name and the stack trace are returned in the response.\n       * See {@link HadoopRpcResponseProto}\n       *\n       * In this method there three types of exceptions possible and they are\n       * returned in response as follows.","sourceCodeStart":511,"sourceCodeEnd":547,"githubUrl":"https://github.com/apache/hadoop/blob/2add9630210752f88ceb1bb74eb65e37bf41da8e/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/ipc/ProtobufRpcEngine2.java#L511-L547","documentation":"Server-side in ProtobufRpcEngine2.ProtoBufRpcInvoker.getProtocolImpl: the (protocolName, clientVersion) pair must exist in the server's registered protocol map; if no implementation of that protocol name exists at all, RpcNoSuchProtocolException('Unknown protocol: X') is thrown back to the client. If the name exists but the version differs you get RPC.VersionMismatch instead — this specific message means the protocol is simply not registered on that server.","triggerScenarios":"Connecting a client of protocol X to a server that never registered X (wrong server type, e.g., ClientNamenodeProtocol sent to a DataNode); protocol class name mismatch (protoName is compared as text); server built without the protocol handler (custom server forgot addProtocol).","commonSituations":"Wrong address/port in client config pointing at a different daemon; custom RPC servers missing RPC.getServer(...).addProtocol(...); shade/relocation renaming protocol classes differently on client vs server; older server that predates the protocol.","solutions":["Verify the target address is the daemon that serves the protocol (NameNode RPC address for ClientNamenodeProtocol, etc.).","On custom servers, register the protocol: server.addProtocol(RpcKind.RPC_PROTOCOL_BUFFER, MyProtocolPB.class, impl).","Ensure the exact same protocol class (name) is used on both sides; avoid jar shading that rewrites class names asymmetrically."],"exampleFix":"// before (custom server)\nRPC.Server server = new RPC.Builder(conf)\n    .setProtocol(MyProtocolPB.class).setInstance(impl)\n    .setBindAddress(\"0.0.0.0\").setPort(8020).build();\n// client sends OtherProtocolPB -> Unknown protocol: OtherProtocolPB\n\n// after\nserver.addProtocol(RPC.RpcKind.RPC_PROTOCOL_BUFFER,\n    OtherProtocolPB.class, otherImpl); // register every served protocol","handlingStrategy":"try-catch","validationCode":"// client capability check before first real call\ntry {\n  proxy.getProtocolMetaInfoNameVersion( // cheap handshake on VersionedProtocol paths\n      null, GetProtocolSignatureRequestProto.newBuilder().setProtocol(protocolName).build());\n} catch (RemoteException e) {\n  if (RpcNoSuchProtocolException.class.getName().equals(e.getErrorCode())) {\n    throw new IllegalStateException(\"Server \" + addr + \" does not serve \" + protocolName, e);\n  }\n  throw e;\n}","typeGuard":null,"tryCatchPattern":"try {\n  return proxy.call(req);\n} catch (RemoteException e) {\n  if (RpcNoSuchProtocolException.class.getName().equals(e.getErrorCode())) {\n    // wrong server or protocol not registered\n    throw new IllegalStateException(\"Wrong endpoint or unregistered protocol\", e);\n  }\n  throw e;\n}","preventionTips":["Always take RPC addresses from the daemon's *-rpc-address config, not the HTTP port.","On custom servers, addProtocol every served interface in one reviewed place.","Keep shading/relocation consistent on both sides so protocol class names match."],"tags":["hadoop","ipc","rpc","protocol","version-mismatch","server"],"backgroundTag":"rpc-unknown-protocol","analyzedSha":"2add9630210752f88ceb1bb74eb65e37bf41da8e","analyzedAt":"2026-08-22T19:55:07.957Z","schemaVersion":2},"datasetVersion":"2026-08-22T20:17:22.307Z"}