apache/hadoop · error · IOException
Expected tag end event for {expected}, but got: {ev}
Error message
Expected tag end event for {expected}, but got: {ev} What it means
expectTagEnd calls expectTag(expected, true) and requires the returned event to be an END_ELEMENT; when a matching (or [...] -group) START_ELEMENT comes back instead, this IOException fires with the full event printed. Concretely it means the stream opened a new element where a close was required - e.g. an extra <inode> appears after the inode loop finished, at the expectTagEnd(INODE_SECTION_NAME) call at OfflineImageReconstructor.java:604.
Source
Thrown at hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/tools/offlineImageViewer/OfflineImageReconstructor.java:237
" instead.");
}
}
return ev;
default:
// Ignore other event types like comment, etc.
if (LOG.isTraceEnabled()) {
LOG.trace("Skipping XMLEvent of type " +
ev.getEventType() + "(" + ev + ")");
}
break;
}
}
}
private void expectTagEnd(String expected) throws IOException {
XMLEvent ev = expectTag(expected, true);
if (ev.getEventType() != XMLStreamConstants.END_ELEMENT) {
throw new IOException("Expected tag end event for " + expected +
", but got: " + ev);
}
if (!expected.startsWith("[")) {
String tag = ev.asEndElement().getName().getLocalPart();
if (!tag.equals(expected)) {
throw new IOException("Expected tag end event for " + expected +
", but got tag end event for " + tag);
}
}
}
private static class Node {
private static final String EMPTY = "";
HashMap<String, LinkedList<Node>> children;
String val = EMPTY;
void addChild(String key, Node node) {
if (children == null) {View on GitHub (pinned to 2add963021)
Solutions
- Make counts agree: either add the missing </inode> closes or raise <numInodes> to the actual entry count
- Check pairing with xmllint --noout (unbalanced tags usually trip well-formedness first)
- Regenerate the dump and apply additions through a DOM tool that recomputes counts
Example fix
<!-- before: 3 entries but numInodes says 2 --> <INodeSection><numInodes>2</numInodes> <inode>...</inode><inode>...</inode><inode>...</inode> </INodeSection> <!-- after --> <INodeSection><numInodes>3</numInodes> <inode>...</inode><inode>...</inode><inode>...</inode> </INodeSection>
Defensive patterns
Strategy: validation
Validate before calling
# No sibling may appear where the section close belongs: counts must agree exactly
declared=$(xmllint --xpath 'string(//INodeSection/numInodes)' fsimage.xml)
actual=$(xmllint --xpath 'count(//inode)' fsimage.xml)
[ "$declared" -eq "$actual" ] || { echo "fix numInodes ($declared) to match $actual entries"; exit 1; } Prevention
- Appending cloned entries requires incrementing the section count in the same change
- Validate tag pairing with xmllint --noout after any append
- Automate insertions with DOM APIs that insert before the closing tag
When it happens
Trigger: More <inode> entries physically present than <numInodes> declares (loop exits, expectTagEnd immediately sees the next START_ELEMENT <inode>); a missing close tag so a sibling start arrives where the section close was expected.
Common situations: Appending cloned inodes to a dump without incrementing <numInodes>; automated inserts that append a full element instead of replacing one.
Related errors
- Failed to find <{expected}>; got {ev.asStartElement().getNam
- Expecting {expected}, but got XMLStreamException
- Got unexpected attribute: {ev}
- Got unxpected characters while looking for {expected}: {ev.a
- Got unexpected end event while looking for {expected}
AI-assisted analysis of apache/hadoop@2add963021 (2026-08-22).
Data as JSON: /api/errors/054e6b8a3d3c74d8.
Report an issue: GitHub.