{"record":{"id":"c481e1a72ec09301","repo":"apache/hadoop","slug":"null-protocol-not-authorized","errorCode":null,"errorMessage":"Null protocol not authorized","messagePattern":"Null protocol not authorized","errorType":"exception","errorClass":"AuthorizationException","httpStatus":null,"severity":"error","filePath":"hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/ipc/Server.java","lineNumber":3909,"sourceCode":"   * @return Call.\n   * @throws Exception raised on errors performing I/O.\n   */\n  public abstract Writable call(RPC.RpcKind rpcKind, String protocol,\n      Writable param, long receiveTime) throws Exception;\n  \n  /**\n   * Authorize the incoming client connection.\n   * \n   * @param user client user\n   * @param protocolName - the protocol\n   * @param addr InetAddress of incoming connection\n   * @throws AuthorizationException when the client isn't authorized to talk the protocol\n   */\n  private void authorize(UserGroupInformation user, String protocolName,\n      InetAddress addr) throws AuthorizationException {\n    if (authorize) {\n      if (protocolName == null) {\n        throw new AuthorizationException(\"Null protocol not authorized\");\n      }\n      Class<?> protocol = null;\n      try {\n        protocol = getProtocolClass(protocolName, getConf());\n      } catch (ClassNotFoundException cfne) {\n        throw new AuthorizationException(\"Unknown protocol: \" + \n                                         protocolName);\n      }\n      serviceAuthorizationManager.authorize(user, protocol, getConf(), addr);\n    }\n  }\n  \n  /**\n   * Get the port on which the IPC Server is listening for incoming connections.\n   * This could be an ephemeral port too, in which case we return the real\n   * port on which the Server has bound.\n   * @return port on which IPC Server is listening\n   */","sourceCodeStart":3891,"sourceCodeEnd":3927,"githubUrl":"https://github.com/apache/hadoop/blob/2add9630210752f88ceb1bb74eb65e37bf41da8e/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/ipc/Server.java#L3891-L3927","documentation":"When service-level authorization is enabled (hadoop.security.authorization=true), Server.authorize must map every incoming connection to a protocol class so the hadoop-policy.xml ACLs can be evaluated. A connection whose header declares no protocol (protocolName == null) cannot be matched against any ACL, so it is rejected with AuthorizationException before any call executes. This is a server-side refusal, not a client-side validation error.","triggerScenarios":"A client opens an IPC connection with a null/absent protocol field in the connection header (protocol-less pings, hand-rolled RPC clients, or an RPC proxy built without setting a protocol class) while the server runs with hadoop.security.authorization=true. Server.authorize(user, null, addr) then throws.","commonSituations":"Enabling service authorization on a cluster that still runs older or third-party clients sending protocol-less headers; custom admin/health-check tools built directly on RPC.Client; version-skewed clients after a rolling upgrade.","solutions":["Make the client declare a protocol: build the proxy with RPC.Builder.setProtocol(...) (or RPC.getProxy/WAITFOR with the protocol class) so the connection header carries a non-null protocol name.","Upgrade the client to a Hadoop version matching the server so the header layout and protocol declaration match.","If the protocol-less connection is intentional (internal liveness check) and cannot be changed, evaluate disabling service authorization (hadoop.security.authorization=false) — accepting the loss of protocol-level ACLs."],"exampleFix":"// before\nRPC.ClientBaseProtocolProbe p = new RPC.ClientBaseProtocolProbe(); // protocol-less connection\n\n// after\nMyProtocol proxy = RPC.getProxy(MyProtocol.class, versionID, addr, ugi, conf, fallback);\n// connection header now carries MyProtocol.class.getName()","handlingStrategy":"try-catch","validationCode":"// Client side: always pass a concrete protocol class so the header is non-null\nif (protocol == null) {\n  throw new IllegalArgumentException(\"protocol class is required when \"\n      + \"hadoop.security.authorization is enabled on the server\");\n}\nT proxy = RPC.getProxy(protocol, version, addr, ugi, conf, null);","typeGuard":null,"tryCatchPattern":"try {\n  proxy.ping();\n} catch (RemoteException re) {\n  if (re.getClassName().endsWith(\"AuthorizationException\")) {\n    // 'Null protocol not authorized': connection header carried no protocol\n    LOG.error(\"Server rejected protocol-less connection: {}\", re.getMessage());\n  }\n}","preventionTips":["Always create proxies with an explicit protocol class (RPC.Builder.setProtocol / RPC.getProxy), never raw protocol-less connections.","When enabling hadoop.security.authorization on a server, inventory every client/tool that connects to it first.","Keep client and server Hadoop versions aligned during rolling upgrades."],"tags":["hadoop","ipc","authorization","acl","security","connection-header"],"backgroundTag":"authorization-denied","analyzedSha":"2add9630210752f88ceb1bb74eb65e37bf41da8e","analyzedAt":"2026-08-22T19:55:07.957Z","schemaVersion":2},"datasetVersion":"2026-08-22T20:17:22.307Z"}