apache/hadoop · error · IOException

Got unexpected end event while looking for {expected}

Error message

Got unexpected end event while looking for {expected}

What it means

expectTag(expected, allowEnd=false) throws when an END_ELEMENT arrives while a specific start tag was mandatory. In this reconstructor it typically fires when a section closes before a required child appears - e.g. </INodeSection> arrives while the reader is still looking for the <inode> entries that <numInodes> promised (the expectTag(INODE_SECTION_INODE, false) call at OfflineImageReconstructor.java:595).

Source

Thrown at hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/tools/offlineImageViewer/OfflineImageReconstructor.java:209

      try {
        ev = events.nextEvent();
      } catch (XMLStreamException e) {
        throw new IOException("Expecting " + expected +
            ", but got XMLStreamException", e);
      }
      switch (ev.getEventType()) {
      case XMLEvent.ATTRIBUTE:
        throw new IOException("Got unexpected attribute: " + ev);
      case XMLEvent.CHARACTERS:
        if (!ev.asCharacters().isWhiteSpace()) {
          throw new IOException("Got unxpected characters while " +
              "looking for " + expected + ": " +
              ev.asCharacters().getData());
        }
        break;
      case XMLEvent.END_ELEMENT:
        if (!allowEnd) {
          throw new IOException("Got unexpected end event " +
              "while looking for " + expected);
        }
        return ev;
      case XMLEvent.START_ELEMENT:
        if (!expected.startsWith("[")) {
          if (!ev.asStartElement().getName().getLocalPart().
                equals(expected)) {
            throw new IOException("Failed to find <" + expected + ">; " +
                "got " + ev.asStartElement().getName().getLocalPart() +
                " instead.");
          }
        }
        return ev;
      default:
        // Ignore other event types like comment, etc.
        if (LOG.isTraceEnabled()) {
          LOG.trace("Skipping XMLEvent of type " +
              ev.getEventType() + "(" +  ev + ")");

View on GitHub (pinned to 2add963021)

Solutions

  1. Fix the count/structure mismatch: restore the missing child elements or update the section's count (e.g. <numInodes>) so the section closes after them
  2. Use the expected-tag name in the message to jump straight to the broken section
  3. Regenerate the XML and reapply the change as a DOM transformation that keeps counts consistent

Example fix

<!-- before: numInodes promises 2 but section ends after 1 entry -->
<INodeSection><lastInodeId>16401</lastInodeId><numInodes>2</numInodes>
  <inode>...</inode>
</INodeSection>

<!-- after -->
<INodeSection><lastInodeId>16401</lastInodeId><numInodes>2</numInodes>
  <inode>...</inode><inode>...</inode>
</INodeSection>
Defensive patterns

Strategy: validation

Validate before calling

# Every count-bearing section must be self-consistent before ReverseXML
declared=$(xmllint --xpath 'string(//INodeSection/numInodes)' fsimage.xml)
actual=$(xmllint --xpath 'count(//inode)' fsimage.xml)
[ "$declared" = "$actual" ] || { echo "numInodes=$declared but $actual <inode> entries"; exit 1; }

Prevention

When it happens

Trigger: ReverseXML after entries were deleted from a section without fixing the section's count field, a closing tag duplicated so the enclosing element ends early, or entries renamed so they no longer match the expected child tag.

Common situations: Pruning inodes/snapshots/blocks by editing XML to 'clean up' a namespace; merges of two sections that drop entries but keep counts.

Related errors


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