apache/hadoop · error · InvalidXmlException
expected a <RECORD> tag
Error message
expected a <RECORD> tag
What it means
Once the version element closes, the loader sits in ParseState.EXPECT_RECORD and each subsequent start element must be <RECORD> (or nothing until </EDITS>). Any other element at that position — stray tags between records, misplaced data elements, or a record child leaking outside its parent — throws InvalidXmlException('expected a <RECORD> tag').
Source
Thrown at hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/tools/offlineEditsViewer/OfflineEditsXmlLoader.java:153
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;
case EXPECT_OPCODE:
if (!name.equals("OPCODE")) {
throw new InvalidXmlException("expected an <OPCODE> tag");
}
break;
case EXPECT_DATA:
if (!name.equals("DATA")) {
throw new InvalidXmlException("expected a <DATA> tag");
}
stanza = new Stanza();
state = ParseState.HANDLE_DATA;
break;
case HANDLE_DATA:
Stanza parent = stanza;
Stanza child = new Stanza();View on GitHub (pinned to 2add963021)
Solutions
- Restructure so every child of <EDITS> after <EDITS_VERSION> is exactly <RECORD>...</RECORD>.
- Re-emit the document from the binary edits with oev instead of repairing nesting by hand.
- Validate against a known-good dump: diff the element sequence (xmllint --shell or a SAX trace) to find the first divergent tag.
Example fix
<!-- before --> <EDITS><EDITS_VERSION>-64</EDITS_VERSION> <DATA><TXID>1</TXID></DATA> <RECORD>...</RECORD></EDITS> <!-- after --> <EDITS><EDITS_VERSION>-64</EDITS_VERSION> <RECORD>...</RECORD></EDITS>
Defensive patterns
Strategy: try-catch
Validate before calling
// Structural walk: after EDITS_VERSION, every start element must be RECORD
try (XMLStreamReader r = XMLInputFactory.newFactory()
.createXMLStreamReader(new FileInputStream(file))) {
r.next(); r.nextTag(); // EDITS
r.nextTag(); // EDITS_VERSION
while (r.hasNext()) {
int ev = r.next();
if (ev == XMLStreamConstants.START_ELEMENT
&& !"RECORD".equals(r.getLocalName())) {
throw new IOException("Expected <RECORD>, found <" + r.getLocalName() + ">");
}
}
} Try / catch
try {
loader.loadEdits();
} catch (InvalidXmlException e) {
if (e.getMessage().contains("<RECORD>")) {
System.err.println("Edits XML has a stray element between records: "
+ e.getMessage() + " - regenerate from binary edits");
}
} Prevention
- Merge edits XML at the record level with a proper XML writer, never by string concatenation.
- Diff the tag sequence against a known-good dump when a merged file starts failing.
When it happens
Trigger: An XML edits file containing an unexpected element between records: e.g. text-structural tags introduced by manual merging, a <DATA> block placed directly under <EDITS>, or duplicated/deeply nested record tags from a broken generator.
Common situations: Concatenating two edits XMLs and leaving duplicate or misplaced fragments; script-generated XML with wrong nesting; diff/patch repairs that reindented content into invalid positions.
Related errors
- expecting </EDITS>
- you must put <EDITS> at the top of the XML file! Got tag {}
- you must put <EDITS_VERSION> at the top of the XML file! Got
- expected an <OPCODE> tag
- expected a <DATA> tag
AI-assisted analysis of apache/hadoop@2add963021 (2026-08-22).
Data as JSON: /api/errors/2d56daca93ef3782.
Report an issue: GitHub.