apache/hadoop · error · InvalidXmlException

you must put <EDITS> at the top of the XML file! Got tag {}

Error message

you must put <EDITS> at the top of the XML file! Got tag {} instead

What it means

The XML edits state machine starts in ParseState.EXPECT_EDITS_TAG, so the very first start-element SAX event must be <EDITS>. Any other root element (or a namespaced/wrapped root the loader does not recognize) throws InvalidXmlException telling you to put <EDITS> at the top. This is a structural guard, not a namespace check: the comparison is on the local name only.

Source

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

    opCode = null;
    cbuf = new StringBuilder();
    nextTxId = -1;
  }
  
  @Override
  public void endDocument() {
    if (state != ParseState.EXPECT_END) {
      throw new InvalidXmlException("expecting </EDITS>");
    }
  }
  
  @Override
  public void startElement (String uri, String name,
      String qName, Attributes atts) {
    switch (state) {
    case EXPECT_EDITS_TAG:
      if (!name.equals("EDITS")) {
        throw new InvalidXmlException("you must put " +
            "<EDITS> at the top of the XML file! " +
            "Got tag " + name + " instead");
      }
      state = ParseState.EXPECT_VERSION;
      break;
    case EXPECT_VERSION:
      if (!name.equals("EDITS_VERSION")) {
        throw new InvalidXmlException("you must put " +
            "<EDITS_VERSION> at the top of the XML file! " +
            "Got tag " + name + " instead");
      }
      break;
    case EXPECT_RECORD:
      if (!name.equals("RECORD")) {
        throw new InvalidXmlException("expected a <RECORD> tag");
      }
      state = ParseState.EXPECT_OPCODE;
      break;

View on GitHub (pinned to 2add963021)

Solutions

  1. Make <EDITS> the outermost element of the file passed to oev's XML loader.
  2. Confirm you are giving oev an edits XML (produced by 'hdfs oev -p xml'), not an fsimage XML.
  3. Regenerate the file from the original binary edits log instead of editing.

Example fix

<!-- before -->
<edits-wrapper><EDITS>...</EDITS></edits-wrapper>

<!-- after -->
<EDITS>...</EDITS>
Defensive patterns

Strategy: validation

Validate before calling

// Root-element check with a streaming reader
XMLInputFactory f = XMLInputFactory.newFactory();
try (XMLStreamReader r = f.createXMLStreamReader(
        new FileInputStream(file))) {
  r.next();
  if (!"EDITS".equals(r.getLocalName())) {
    throw new IOException("Root element must be <EDITS>, found <"
        + r.getLocalName() + ">");
  }
}

Try / catch

try {
  loader.loadEdits();
} catch (InvalidXmlException e) {
  if (e.getMessage().contains("top of the XML file")) {
    throw new IOException("Wrong document structure: " + e.getMessage()
        + ". Use an edits XML produced by 'hdfs oev -p xml'.", e);
  }
  throw e;
}

Prevention

When it happens

Trigger: Feeding oev an XML file whose root element is not EDITS — e.g. an fsimage XML, a generic configuration XML, or an edits document wrapped inside another element.

Common situations: Pointing -i at the wrong file after renaming outputs; merging XMLs under a synthetic root; confusing offlineImageViewer (oiv) output with offlineEditsViewer (oev) input.

Related errors


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