{"record":{"id":"383591782deded57","repo":"apache/hadoop","slug":"handler-returned-null","errorCode":null,"errorMessage":"Handler returned null.","messagePattern":"Handler returned null\\.","errorType":"exception","errorClass":"NullPointerException","httpStatus":null,"severity":"error","filePath":"hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/ipc/RefreshRegistry.java","lineNumber":116,"sourceCode":"      String msg = \"Identifier '\" + identifier +\n        \"' does not exist in RefreshRegistry. Valid options are: \" +\n        Joiner.on(\", \").join(handlerTable.keySet());\n\n      throw new IllegalArgumentException(msg);\n    }\n\n    ArrayList<RefreshResponse> responses =\n      new ArrayList<RefreshResponse>(handlers.size());\n\n    // Dispatch to each handler and store response\n    for(RefreshHandler handler : handlers) {\n      RefreshResponse response;\n\n      // Run the handler\n      try {\n        response = handler.handleRefresh(identifier, args);\n        if (response == null) {\n          throw new NullPointerException(\"Handler returned null.\");\n        }\n\n        LOG.info(handlerName(handler) + \" responds to '\" + identifier +\n          \"', says: '\" + response.getMessage() + \"', returns \" +\n          response.getReturnCode());\n      } catch (Exception e) {\n        response = new RefreshResponse(-1, e.getLocalizedMessage());\n      }\n\n      response.setSenderName(handlerName(handler));\n      responses.add(response);\n    }\n\n    return responses;\n  }\n\n  private String handlerName(RefreshHandler h) {\n    return h.getClass().getName() + '@' + Integer.toHexString(h.hashCode());","sourceCodeStart":98,"sourceCodeEnd":134,"githubUrl":"https://github.com/apache/hadoop/blob/2add9630210752f88ceb1bb74eb65e37bf41da8e/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/ipc/RefreshRegistry.java#L98-L134","documentation":"RefreshRegistry.dispatch requires every RefreshHandler.handleRefresh to return a non-null RefreshResponse. A null return raises NullPointerException(\"Handler returned null.\") inside the per-handler loop, which the surrounding catch immediately converts into a RefreshResponse(-1, localizedMessage) — the admin client sees a failed refresh carrying this message, and the server stays up. It always indicates a bug in the handler implementation.","triggerScenarios":"A RefreshHandler implementation with a code path that returns null: an early-exit branch for unrecognized arguments, a missing final return after refactoring, or a third-party plugin registered as a refreshable.","commonSituations":"Custom refresh handlers where one branch forgets to build a response; copied handler skeletons where the error path is a stub 'return null'; refactors of handleRefresh that drop the trailing return statement.","solutions":["Make handleRefresh return a RefreshResponse on every path — failures as new RefreshResponse(-1, \"reason\").","Return a success response (e.g., RefreshResponse.success(...)) as the default last line so no path can fall through to null.","Add unit tests covering every argument branch of handleRefresh to catch null paths before deployment."],"exampleFix":"// before\n@Override\npublic RefreshResponse handleRefresh(String identifier, String[] args) {\n  if (args.length != 1) {\n    return null; // becomes RefreshResponse(-1, \"Handler returned null.\")\n  }\n  return doRefresh(args[0]);\n}\n// after\n@Override\npublic RefreshResponse handleRefresh(String identifier, String[] args) {\n  if (args.length != 1) {\n    return new RefreshResponse(-1, \"expected exactly 1 argument\");\n  }\n  return doRefresh(args[0]);\n}","handlingStrategy":"validation","validationCode":"// defensive wrapper when invoking handlers you do not own\nRefreshResponse r;\ntry {\n  r = handler.handleRefresh(id, args);\n} catch (Exception e) {\n  r = new RefreshResponse(-1, e.getLocalizedMessage());\n}\nif (r == null) {\n  r = new RefreshResponse(-1, \"handler returned null\");\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Never return null from handleRefresh — every branch returns a RefreshResponse.","End the method with a default success response so no path falls through.","Treat a '-1 Handler returned null.' response as a handler bug to fix, not an operational condition."],"tags":["refresh","handler","null-return","admin"],"backgroundTag":"null-return-value","analyzedSha":"2add9630210752f88ceb1bb74eb65e37bf41da8e","analyzedAt":"2026-08-22T19:55:07.957Z","schemaVersion":2},"datasetVersion":"2026-08-22T20:17:22.307Z"}