apache/hadoop · error · IOException

Tried to exit non-existent enclosing element in FSImage file

Error message

Tried to exit non-existent enclosing element in FSImage file

What it means

The legacy XML outputter (oiv_legacy -p XML, XmlImageVisitor) keeps a stack of currently open elements and pops it in leaveEnclosingElement(). The stack was empty when a close was requested, meaning the visitor emitted more leave-element calls than start-element calls — an internal bookkeeping imbalance in the legacy visitor logic (or a custom subclass), not a user configuration error.

Source

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

       throws IOException {
    super(filename, printToScreen);
  }

  @Override
  void finish() throws IOException {
    super.finish();
  }

  @Override
  void finishAbnormally() throws IOException {
    write("\n<!-- Error processing image file.  Exiting -->\n");
    super.finishAbnormally();
  }

  @Override
  void leaveEnclosingElement() throws IOException {
    if (tagQ.isEmpty()) {
      throw new IOException("Tried to exit non-existent enclosing element " +
          "in FSImage file");
    }

    ImageElement element = tagQ.pop();
    write("</" + element.toString() + ">\n");
  }

  @Override
  void start() throws IOException {
    write("<?xml version=\"1.0\" ?>\n");
  }

  @Override
  void visit(ImageElement element, String value) throws IOException {
    writeTag(element.toString(), value);
  }

  @Override

View on GitHub (pinned to 2add963021)

Solutions

  1. Try other legacy processors (`-p Lsr`, `-p Indented`, `-p Delimited`); if they succeed, the XML visitor hit an imbalance — file a HADOOP JIRA with the image
  2. In custom visitor subclasses, audit that every leaveEnclosingElement() has a matching startElement() on all paths including exception paths
  3. For Hadoop 2.x+ images use `hdfs oiv -p XML` (PBImageXmlWriter), which does not share this code

Example fix

// before: custom visitor leaves an element it never opened
visitor.startElement(ImageElement.INODE);
if (listChildren) {
  emitChildren(visitor);
}
visitor.leaveEnclosingElement(); // also runs when emitChildren already left

// after: only leave what this code path opened
if (!listChildren) {
  visitor.leaveEnclosingElement();
}
Defensive patterns

Strategy: try-catch

Try / catch

try {
  new OfflineImageViewer(inputFile, new XmlImageVisitor(out, false), false).go();
} catch (IOException e) {
  if (e.getMessage().contains("non-existent enclosing element")) {
    // internal visitor imbalance: try Lsr/Indented processors to confirm the
    // image parses, then report the image upstream
    LOG.error("legacy XML visitor stack imbalance on {}", inputFile, e);
  }
  throw e;
}

Prevention

When it happens

Trigger: Walking an old-format fsimage whose constructs hit an unbalanced start/leave path in oiv_legacy's XML visitor; or subclassing XmlImageVisitor with a leaveEnclosingElement() call that has no matching startElement() on some code path.

Common situations: Running `hdfs oiv_legacy -p XML` over pre-2.x images with symlinks/snapshots; custom visitor subclasses that skip startElement on edge cases.

Related errors


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