{"record":{"id":"c0a0b051c0ace7f8","repo":"apache/hadoop","slug":"expected-edits","errorCode":null,"errorMessage":"expected <EDITS/>","messagePattern":"expected <EDITS/>","errorType":"validation","errorClass":"InvalidXmlException","httpStatus":null,"severity":"error","filePath":"hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/tools/offlineEditsViewer/OfflineEditsXmlLoader.java","lineNumber":187,"sourceCode":"    case HANDLE_DATA:\n      Stanza parent = stanza;\n      Stanza child = new Stanza();\n      stanzaStack.push(parent);\n      stanza = child;\n      parent.addChild(name, child);\n      break;\n    case EXPECT_END:\n      throw new InvalidXmlException(\"not expecting anything after </EDITS>\");\n    }\n  }\n  \n  @Override\n  public void endElement (String uri, String name, String qName) {\n    String str = XMLUtils.unmangleXmlString(cbuf.toString(), false).trim();\n    cbuf = new StringBuilder();\n    switch (state) {\n    case EXPECT_EDITS_TAG:\n      throw new InvalidXmlException(\"expected <EDITS/>\");\n    case EXPECT_VERSION:\n      if (!name.equals(\"EDITS_VERSION\")) {\n        throw new InvalidXmlException(\"expected </EDITS_VERSION>\");\n      }\n      try {\n        int version = Integer.parseInt(str);\n        visitor.start(version);\n      } catch (IOException e) {\n        // Can't throw IOException from a SAX method, sigh.\n        throw new RuntimeException(e);\n      }\n      state = ParseState.EXPECT_RECORD;\n      break;\n    case EXPECT_RECORD:\n      if (name.equals(\"EDITS\")) {\n        state = ParseState.EXPECT_END;\n      } else if (!name.equals(\"RECORD\")) {\n        throw new InvalidXmlException(\"expected </EDITS> or </RECORD>\");","sourceCodeStart":169,"sourceCodeEnd":205,"githubUrl":"https://github.com/apache/hadoop/blob/2add9630210752f88ceb1bb74eb65e37bf41da8e/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/tools/offlineEditsViewer/OfflineEditsXmlLoader.java#L169-L205","documentation":"OfflineEditsXmlLoader parses OEV XML edits files with a strict SAX state machine whose only legal root is <EDITS>. This exception is thrown from endElement() when a closing tag arrives while the state is still EXPECT_EDITS_TAG, i.e. an end-element event occurred before the opening <EDITS> root element was ever seen. It is an InvalidXmlException (a RuntimeException) which loadEdits() rethrows after calling visitor.close(e).","triggerScenarios":"Running 'hdfs oev' with XML input (e.g. hdfs oev -i edits.xml -o out -p BINARY) on a file whose first element event is an endElement: a document that starts with a closing tag, or any non-edits XML whose structure produces a close before <EDITS> opens.","commonSituations":"Feeding the wrong XML file (a config file, web.xml, another tool's output) to the offline edits viewer; hand-editing an oev XML dump and deleting/renaming the <EDITS> root; scripts that splice or generate XML without the required skeleton.","solutions":["Regenerate the input from a real binary edit log: hdfs oev -i edits_inprogress-0000000001 -p XML -o edits.xml, then feed that file back in.","Open the file and confirm the very first tag is exactly <EDITS> with no preceding elements and no stray closing tags.","If hand-authored, rebuild it following the skeleton <EDITS><EDITS_VERSION>-63</EDITS_VERSION><RECORD><OPCODE>...</OPCODE><DATA>...</DATA></RECORD>...</EDITS>.","Sanity-check the file first with xmllint --noout edits.xml to rule out gross malformation."],"exampleFix":"// before (edits.xml)\n</EDITS>\n<EDITS><EDITS_VERSION>-63</EDITS_VERSION>...\n\n// after (edits.xml)\n<?xml version=\"1.0\"?>\n<EDITS><EDITS_VERSION>-63</EDITS_VERSION>\n  <RECORD><OPCODE>OP_MKDIR</OPCODE><DATA>...</DATA></RECORD>\n</EDITS>","handlingStrategy":"try-catch","validationCode":"private static boolean startsWithEditsRoot(File f) throws IOException {\n  try (BufferedReader r = new BufferedReader(new InputStreamReader(\n      new FileInputStream(f), StandardCharsets.UTF_8))) {\n    String line = r.readLine();\n    while (line != null && line.trim().isEmpty()) line = r.readLine();\n    return line != null && line.trim().startsWith(\"<EDITS\");\n  }\n}","typeGuard":null,"tryCatchPattern":"try {\n  OfflineEditsViewer.go(args, System.out);  // or loader.loadEdits()\n} catch (InvalidXmlException e) {\n  // Input does not follow the OEV XML skeleton; regenerate it with oev\n  LOG.error(\"Not an OEV XML file: \" + e.getMessage());\n}","preventionTips":["Only feed oev XML that oev itself produced (round-trip guarantee).","Never hand-edit the XML structure; at most edit field values.","Keep a known-good edits.xml and diff new inputs against its skeleton.","Run xmllint --noout before conversion to catch gross malformation cheaply."],"tags":["hdfs","offline-edits-viewer","oev","edit-log","xml","sax"],"backgroundTag":"malformed-xml-input","analyzedSha":"2add9630210752f88ceb1bb74eb65e37bf41da8e","analyzedAt":"2026-08-22T19:55:07.957Z","schemaVersion":2},"datasetVersion":"2026-08-22T20:17:22.307Z"}