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
- 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.
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
- 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.
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
- expected </EDITS_VERSION>
- expected </EDITS> or </RECORD>
- expected </OPCODE>
- expected <DATA/>
- expected </DATA>
AI-assisted analysis of apache/hadoop@2add963021 (2026-08-22).
Data as JSON: /api/errors/c0a0b051c0ace7f8.
Report an issue: GitHub.