{"record":{"id":"644291eafe33a02e","repo":"apache/hadoop","slug":"failed-to-read-fields-from-setaclop","errorCode":null,"errorMessage":"Failed to read fields from SetAclOp","messagePattern":"Failed to read fields from SetAclOp","errorType":"exception","errorClass":"java.io.IOException","httpStatus":null,"severity":"error","filePath":"hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/namenode/FSEditLogOp.java","lineNumber":4422,"sourceCode":"    SetAclOp() {\n      super(OP_SET_ACL);\n    }\n\n    static SetAclOp getInstance(OpInstanceCache cache) {\n      return cache.get(OP_SET_ACL);\n    }\n\n    @Override\n    void resetSubFields() {\n      aclEntries = null;\n      src = null;\n    }\n\n    @Override\n    void readFields(DataInputStream in, int logVersion) throws IOException {\n      AclEditLogProto p = AclEditLogProto.parseDelimitedFrom(in);\n      if (p == null) {\n        throw new IOException(\"Failed to read fields from SetAclOp\");\n      }\n      src = p.getSrc();\n      aclEntries = PBHelperClient.convertAclEntry(p.getEntriesList());\n    }\n\n    @Override\n    public void writeFields(DataOutputStream out) throws IOException {\n      AclEditLogProto.Builder b = AclEditLogProto.newBuilder();\n      if (src != null)\n        b.setSrc(src);\n      b.addAllEntries(PBHelperClient.convertAclEntryProto(aclEntries));\n      b.build().writeDelimitedTo(out);\n    }\n\n    @Override\n    protected void toXml(ContentHandler contentHandler) throws SAXException {\n      XMLUtils.addSaxString(contentHandler, \"SRC\", src);\n      appendAclEntriesToXml(contentHandler, aclEntries);","sourceCodeStart":4404,"sourceCodeEnd":4440,"githubUrl":"https://github.com/apache/hadoop/blob/2add9630210752f88ceb1bb74eb65e37bf41da8e/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/namenode/FSEditLogOp.java#L4404-L4440","documentation":"SetAclOp.readFields() parses its record body as a length-delimited protobuf (AclEditLogProto.parseDelimitedFrom). parseDelimitedFrom returns null exactly when EOF is reached before the message's length prefix, which this code converts into an IOException: the segment ends in the middle of an OP_SET_ACL record.","triggerScenarios":"Replaying an edits_inprogress or finalized segment truncated mid-OP_SET_ACL: NameNode killed or the journal disk filled during the write, a short HTTP/JournalNode transfer delivered an incomplete file, or bit rot consumed the tail.","commonSituations":"Unclean shutdown followed by restart; full journal disks; standby bootstrap or offlineEditsViewer pulling a truncated segment over a flaky network; corrupted transfers between JNs.","solutions":["Run 'hdfs namenode -recover' to skip the truncated tail record, then immediately checkpoint","Inspect the segment with 'hdfs offlineEditsViewer -i <edits> -o out.xml' to confirm where it truncates","Fetch a complete copy of the same segment from a healthy JournalNode (QJM majority) and replace the short file","If only the local copy exists and is truncated, discard it and recover from the last fsimage plus valid journals; also fix the root cause (disk space, network) before restarting"],"exampleFix":"# before\nhdfs namenode   # IOException: Failed to read fields from SetAclOp\n# after\nhdfs namenode -recover   # skip the truncated tail, then: hdfs dfsadmin -saveNamespace","handlingStrategy":"try-catch","validationCode":"# verify every segment is complete before replay/bootstrap\nhdfs offlineEditsViewer -i edits_inprogress_0000000000000001234 -o /dev/null\n# a truncated protobuf tail fails here instead of during NameNode start","typeGuard":null,"tryCatchPattern":"try {\n  FSEditLogOp op = reader.readOp();\n} catch (IOException e) {\n  if (e.getMessage().contains(\"Failed to read fields from SetAclOp\")) {\n    // segment truncated mid-OP_SET_ACL: recover with 'hdfs namenode -recover'\n    // or refetch the complete segment from a healthy JournalNode\n  } else { throw e; }\n}","preventionTips":["Keep journal disks below capacity alerts; disk-full truncates in-flight records","After a crash, validate edits_inprogress with offlineEditsViewer before restart","Run QJM so a complete copy of every segment always exists elsewhere","Verify network health between NN/JN/SNN — truncated transfers produce short segments"],"tags":["hdfs","edit-log","protobuf","acl","corruption","truncation"],"backgroundTag":"truncated-protobuf-message","analyzedSha":"2add9630210752f88ceb1bb74eb65e37bf41da8e","analyzedAt":"2026-08-22T19:55:07.957Z","schemaVersion":2},"datasetVersion":"2026-08-23T01:17:44.959Z"}