apache/hadoop · error · InvalidXmlException
expecting </EDITS>
Error message
expecting </EDITS>
What it means
When offlineEditsViewer reads an XML edits file (-p xml input or XmlEditsVisitors round-trip), OfflineEditsXmlLoader drives a SAX handler as a strict state machine. endDocument() must find the machine in ParseState.EXPECT_END, reached only after the closing </EDITS> tag has been consumed with a well-formed record sequence. Any other final state throws InvalidXmlException('expecting </EDITS>') — in practice the document ended early, most often a truncated file cut off before the closing tag.
Source
Thrown at hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/tools/offlineEditsViewer/OfflineEditsXmlLoader.java:128
} finally {
fileReader.close();
}
}
@Override
public void startDocument() {
state = ParseState.EXPECT_EDITS_TAG;
stanza = null;
stanzaStack = new Stack<Stanza>();
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 " +View on GitHub (pinned to 2add963021)
Solutions
- Re-generate the XML from the source binary edits log with 'hdfs oev -i <edits> -o out.xml -p xml' rather than repairing by hand.
- If the source is gone, restore the tail (at minimum a well-formed sequence of closed records plus </EDITS>) from a backup or snapshot of the XML.
- Sanity-check the file first: 'tail -n 5 file.xml' should show </EDITS>, and xmllint --noout reports where well-formedness breaks.
Example fix
<!-- before: file ends abruptly --> <RECORD><OPCODE>9</OPCODE><DATA>...unbalanced... <!-- after: complete document --> <EDITS><EDITS_VERSION>-64</EDITS_VERSION> <RECORD><OPCODE>9</OPCODE><DATA>...</DATA></RECORD> </EDITS>
Defensive patterns
Strategy: try-catch
Validate before calling
// Cheap structural pre-check before handing the file to oev
List<String> tail = Files.readAllLines(Path.of(file)).size() > 5
? Files.readAllLines(Path.of(file)).subList(
Files.readAllLines(Path.of(file)).size() - 5,
Files.readAllLines(Path.of(file)).size()) : List.of();
if (tail.stream().noneMatch(l -> l.trim().equals("</EDITS>"))) {
throw new IOException(file + " does not end with </EDITS>; likely truncated");
} Try / catch
try {
OfflineEditsLoader loader = OfflineEditsLoader.createLoader(visitor);
loader.loadEdits();
} catch (InvalidXmlException e) {
// SAX-state failure: message names what the machine expected
System.err.println("Edits XML malformed: " + e.getMessage()
+ " - regenerate with 'hdfs oev -p xml' from the binary edits");
} Prevention
- Treat oev XML as generated output only: never hand-edit, merge, or truncate it.
- After copying large XML dumps, verify size/checksum and that the last line is </EDITS> before processing.
- Keep the original binary edits files so any XML can be regenerated.
When it happens
Trigger: Feeding oev an edits XML file that is truncated (missing or unclosed </EDITS>), or one whose records stopped mid-structure, e.g. partial copy from a crashed scp, log rotation artifact, or manual editing that deleted the tail.
Common situations: Copying a large edits XML over a flaky link and getting a short file; regenerating XML by concatenation that dropped the last line; hand-trimming files for test fixtures.
Related errors
- 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 a <RECORD> tag
- expected an <OPCODE> tag
- expected a <DATA> tag
AI-assisted analysis of apache/hadoop@2add963021 (2026-08-22).
Data as JSON: /api/errors/a4c3bfefa4daffe1.
Report an issue: GitHub.