apache/hadoop · error · InvalidXmlException

expected <EDITS/>

Error message

expected <EDITS/>

What it means

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).

Source

Thrown at hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/tools/offlineEditsViewer/OfflineEditsXmlLoader.java:187

    case HANDLE_DATA:
      Stanza parent = stanza;
      Stanza child = new Stanza();
      stanzaStack.push(parent);
      stanza = child;
      parent.addChild(name, child);
      break;
    case EXPECT_END:
      throw new InvalidXmlException("not expecting anything after </EDITS>");
    }
  }
  
  @Override
  public void endElement (String uri, String name, String qName) {
    String str = XMLUtils.unmangleXmlString(cbuf.toString(), false).trim();
    cbuf = new StringBuilder();
    switch (state) {
    case EXPECT_EDITS_TAG:
      throw new InvalidXmlException("expected <EDITS/>");
    case EXPECT_VERSION:
      if (!name.equals("EDITS_VERSION")) {
        throw new InvalidXmlException("expected </EDITS_VERSION>");
      }
      try {
        int version = Integer.parseInt(str);
        visitor.start(version);
      } catch (IOException e) {
        // Can't throw IOException from a SAX method, sigh.
        throw new RuntimeException(e);
      }
      state = ParseState.EXPECT_RECORD;
      break;
    case EXPECT_RECORD:
      if (name.equals("EDITS")) {
        state = ParseState.EXPECT_END;
      } else if (!name.equals("RECORD")) {
        throw new InvalidXmlException("expected </EDITS> or </RECORD>");

View on GitHub (pinned to 2add963021)

Solutions

  1. 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.
  2. Open the file and confirm the very first tag is exactly <EDITS> with no preceding elements and no stray closing tags.
  3. If hand-authored, rebuild it following the skeleton <EDITS><EDITS_VERSION>-63</EDITS_VERSION><RECORD><OPCODE>...</OPCODE><DATA>...</DATA></RECORD>...</EDITS>.
  4. Sanity-check the file first with xmllint --noout edits.xml to rule out gross malformation.

Example fix

// before (edits.xml)
</EDITS>
<EDITS><EDITS_VERSION>-63</EDITS_VERSION>...

// after (edits.xml)
<?xml version="1.0"?>
<EDITS><EDITS_VERSION>-63</EDITS_VERSION>
  <RECORD><OPCODE>OP_MKDIR</OPCODE><DATA>...</DATA></RECORD>
</EDITS>
Defensive patterns

Strategy: try-catch

Validate before calling

private static boolean startsWithEditsRoot(File f) throws IOException {
  try (BufferedReader r = new BufferedReader(new InputStreamReader(
      new FileInputStream(f), StandardCharsets.UTF_8))) {
    String line = r.readLine();
    while (line != null && line.trim().isEmpty()) line = r.readLine();
    return line != null && line.trim().startsWith("<EDITS");
  }
}

Try / catch

try {
  OfflineEditsViewer.go(args, System.out);  // or loader.loadEdits()
} catch (InvalidXmlException e) {
  // Input does not follow the OEV XML skeleton; regenerate it with oev
  LOG.error("Not an OEV XML file: " + e.getMessage());
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of apache/hadoop@2add963021 (2026-08-22). Data as JSON: /api/errors/c0a0b051c0ace7f8. Report an issue: GitHub.