{"record":{"id":"d6dd66130832e2d2","repo":"apache/hadoop","slug":"snapshot-section-was-missing-id","errorCode":null,"errorMessage":"<snapshot> section was missing <id>","messagePattern":"<snapshot> section was missing <id>","errorType":"exception","errorClass":"IOException","httpStatus":null,"severity":"error","filePath":"hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/tools/offlineImageViewer/OfflineImageReconstructor.java","lineNumber":1382,"sourceCode":"      }\n      header.verifyNoRemainingKeys(\"SnapshotSection\");\n      bld.build().writeDelimitedTo(out);\n      int actualNumSnapshots = 0;\n      while (actualNumSnapshots < expectedNumSnapshots) {\n        try {\n          expectTag(SNAPSHOT_SECTION_SNAPSHOT, false);\n        } catch (IOException e) {\n          throw new IOException(\"Only read \" + actualNumSnapshots +\n              \" <snapshot> entries out of \" + expectedNumSnapshots, e);\n        }\n        actualNumSnapshots++;\n        Node snapshot = new Node();\n        loadNodeChildren(snapshot, \"snapshot fields\");\n        FsImageProto.SnapshotSection.Snapshot.Builder s =\n            FsImageProto.SnapshotSection.Snapshot.newBuilder();\n        Integer snapshotId = snapshot.removeChildInt(SECTION_ID);\n        if (snapshotId == null) {\n          throw new IOException(\"<snapshot> section was missing <id>\");\n        }\n        s.setSnapshotId(snapshotId);\n        Node snapshotRoot = snapshot.removeChild(SNAPSHOT_SECTION_ROOT);\n        INodeSection.INode.Builder inodeBld = processINodeXml(snapshotRoot);\n        s.setRoot(inodeBld);\n        s.build().writeDelimitedTo(out);\n      }\n      expectTagEnd(SNAPSHOT_SECTION_NAME);\n      recordSectionLength(SectionName.SNAPSHOT.name());\n    }\n  }\n\n  private class SnapshotDiffSectionProcessor implements SectionProcessor {\n    static final String NAME = \"SnapshotDiffSection\";\n\n    @Override\n    public void process() throws IOException {\n      // No header for this section type.","sourceCodeStart":1364,"sourceCodeEnd":1400,"githubUrl":"https://github.com/apache/hadoop/blob/2add9630210752f88ceb1bb74eb65e37bf41da8e/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/tools/offlineImageViewer/OfflineImageReconstructor.java#L1364-L1400","documentation":"ReverseXML found a <snapshot> element inside <SnapshotSection> whose <id> child is absent. The protobuf Snapshot message requires snapshotId, so after loading the element's children into the Node tree, removeChildInt(\"id\") returned null and reconstruction aborts. Note the required tag is exactly <id>, not <snapshotId>.","triggerScenarios":"A <snapshot> element with no <id> child - typically deleted or renamed during hand-editing (e.g. changed to <snapshotId> or <sid>), or XML written from scratch by a script that never emitted it.","commonSituations":"Hand-edited XML where <id> was renamed for readability; synthetic XML authored without studying the oiv XML schema; field-name drift between Hadoop releases' XML writers.","solutions":["Add <id>NUMBER</id> as a child of each affected <snapshot> element, using the snapshot's numeric ID","If the tag was renamed (e.g. <snapshotId>), rename it back to exactly <id> - the parser matches the literal tag name","Regenerate the XML from a binary fsimage with a matching-version oiv and reapply edits","Diff against a known-good dump to catch other renamed/missing fields"],"exampleFix":"<!-- before -->\n<snapshot><snapshotId>101</snapshotId><root>...</root></snapshot>\n<!-- after -->\n<snapshot><id>101</id><root>...</root></snapshot>","handlingStrategy":"validation","validationCode":"# python: every <snapshot> must carry an <id> child\nimport xml.etree.ElementTree as ET\n\ndef snapshots_have_ids(path):\n    for ev, el in ET.iterparse(path, events=('end',)):\n        if el.tag == 'snapshot' and el.find('id') is None:\n            return False\n    return True","typeGuard":null,"tryCatchPattern":"try {\n  int rc = new ProcessBuilder(\"hdfs\",\"oiv\",\"-processor\",\"ReverseXML\",\n      \"-i\", xml, \"-o\", out).inheritIO().start().waitFor();\n  if (rc != 0) throw new IllegalStateException(\"reconstruction failed: \" + xml);\n} catch (IOException | InterruptedException e) {\n  throw new RuntimeException(\"cannot run oiv\", e);\n}","preventionTips":["Use the exact oiv-emitted tag names (<id>, not <snapshotId>) when editing","Diff against a known-good dump before reconstructing edited XML","Automate edits with scripts that preserve required children","Regenerate from the binary fsimage whenever the XML schema is uncertain"],"tags":["hdfs","oiv","fsimage","reversexml","snapshot","missing-field"],"backgroundTag":"missing-required-xml-element","analyzedSha":"2add9630210752f88ceb1bb74eb65e37bf41da8e","analyzedAt":"2026-08-22T19:55:07.957Z","schemaVersion":2},"datasetVersion":"2026-08-23T01:17:44.959Z"}