apache/hadoop · error · IOException

<dirDiffEntry> contained no <count> entry.

Error message

<dirDiffEntry> contained no <count> entry.

What it means

A <dirDiffEntry> header is missing its <count> child, which tells the reconstructor how many <dirDiff> elements follow. Without it the protobuf DiffEntry.numOfDiff cannot be set, so the tool aborts before reading any diffs for this inode.

Source

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

      recordSectionLength(SectionName.SNAPSHOT_DIFF.name());
    }

    private void processDirDiffEntry() throws IOException {
      LOG.debug("Processing dirDiffEntry");
      DiffEntry.Builder headerBld = DiffEntry.newBuilder();
      headerBld.setType(DiffEntry.Type.DIRECTORYDIFF);
      Node dirDiffHeader = new Node();
      loadNodeChildren(dirDiffHeader, "dirDiffEntry fields", "dirDiff");
      Long inodeId = dirDiffHeader.removeChildLong(
          SNAPSHOT_DIFF_SECTION_INODE_ID);
      if (inodeId == null) {
        throw new IOException("<dirDiffEntry> contained no <inodeId> entry.");
      }
      headerBld.setInodeId(inodeId);
      Integer expectedDiffs = dirDiffHeader.removeChildInt(
          SNAPSHOT_DIFF_SECTION_COUNT);
      if (expectedDiffs == null) {
        throw new IOException("<dirDiffEntry> contained no <count> entry.");
      }
      headerBld.setNumOfDiff(expectedDiffs);
      dirDiffHeader.verifyNoRemainingKeys("dirDiffEntry");
      headerBld.build().writeDelimitedTo(out);
      for (int actualDiffs = 0; actualDiffs < expectedDiffs; actualDiffs++) {
        try {
          expectTag(SNAPSHOT_DIFF_SECTION_DIR_DIFF, false);
        } catch (IOException e) {
          throw new IOException("Only read " + (actualDiffs + 1) +
              " diffs out of " + expectedDiffs, e);
        }
        Node dirDiff = new Node();
        loadNodeChildren(dirDiff, "dirDiff fields");
        FsImageProto.SnapshotDiffSection.DirectoryDiff.Builder bld =
            FsImageProto.SnapshotDiffSection.DirectoryDiff.newBuilder();
        Integer snapshotId = dirDiff.removeChildInt(
            SNAPSHOT_DIFF_SECTION_SNAPSHOT_ID);
        if (snapshotId != null) {

View on GitHub (pinned to 2add963021)

Solutions

  1. Add <count>N</count> to the entry header, where N is the number of <dirDiff> children that follow
  2. Count the <dirDiff> elements in the entry and make <count> match exactly
  3. Confirm <count> appears before the first <dirDiff>
  4. Regenerate the XML with a matching-version oiv

Example fix

<!-- before: no count -->
<dirDiffEntry><inodeId>16386</inodeId>
  <dirDiff>...</dirDiff><dirDiff>...</dirDiff>
</dirDiffEntry>
<!-- after -->
<dirDiffEntry><inodeId>16386</inodeId><count>2</count>
  <dirDiff>...</dirDiff><dirDiff>...</dirDiff>
</dirDiffEntry>
Defensive patterns

Strategy: validation

Validate before calling

# python: every dirDiffEntry needs <count> equal to its <dirDiff> children
import xml.etree.ElementTree as ET

def dir_counts_ok(path):
    for ev, el in ET.iterparse(path, events=('end',)):
        if el.tag == 'dirDiffEntry':
            c = el.find('count')
            if c is None or int(c.text) != len(el.findall('dirDiff')):
                return False
    return True

Try / catch

// catch non-zero oiv exit; message names the entry missing <count>
// fix the header, remove the partial output file, re-run

Prevention

When it happens

Trigger: A <dirDiffEntry> whose <count> was omitted or renamed during editing, or whose header was restructured so <count> ended up after the first <dirDiff> (headers stop at that terminator).

Common situations: Entries hand-written or script-generated without the count; counts removed because they 'looked redundant'; XML from a writer version that used a different field name.

Related errors


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