apache/hadoop · critical · IOException

Negative length of the file

Error message

Negative length of the file

What it means

A protobuf fsimage ends with a length-prefixed FileSummary: the last 4 bytes are an int holding the summary length. FSImageUtil.loadSummary() seeks to the tail, reads that int, and rejects values <= 0 — exactly what a truncated or zero-filled tail produces. It means the image file is incomplete (disk full while saving, crash mid-write, interrupted copy), not a version problem.

Source

Thrown at hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/namenode/FSImageUtil.java:61

      return false;

    byte[] magic = new byte[MAGIC_HEADER.length];
    file.readFully(magic);
    if (!Arrays.equals(MAGIC_HEADER, magic))
      return false;

    return true;
  }

  public static FileSummary loadSummary(RandomAccessFile file)
      throws IOException {
    final int FILE_LENGTH_FIELD_SIZE = 4;
    long fileLength = file.length();
    file.seek(fileLength - FILE_LENGTH_FIELD_SIZE);
    int summaryLength = file.readInt();

    if (summaryLength <= 0) {
      throw new IOException("Negative length of the file");
    }
    file.seek(fileLength - FILE_LENGTH_FIELD_SIZE - summaryLength);

    byte[] summaryBytes = new byte[summaryLength];
    file.readFully(summaryBytes);

    FileSummary summary = FileSummary
        .parseDelimitedFrom(new ByteArrayInputStream(summaryBytes));
    if (summary.getOndiskVersion() != FILE_VERSION) {
      throw new IOException("Unsupported file version "
          + summary.getOndiskVersion());
    }

    if (!NameNodeLayoutVersion.supports(Feature.PROTOBUF_FORMAT,
        summary.getLayoutVersion())) {
      throw new IOException("Unsupported layout version "
          + summary.getLayoutVersion());
    }

View on GitHub (pinned to 2add963021)

Solutions

  1. Check the file size and verify against the paired fsimage.md5; recopy if the checksum fails
  2. Restore the image from another name.dir or backup — the truncated copy is unusable
  3. If a save failed, the previous fsimage is usually still present: remove the partial newest image and boot from the prior txid
  4. Monitor free space on the name dirs so checkpoints never run against a full disk

Example fix

# before: truncated image fails to load
ls -l /dfs/name/current/   # fsimage_0000000000000090000 suspiciously small
# after: drop the partial file, boot from the previous good image
cd /dfs/name/current && rm fsimage_0000000000000090000*
cp /backup/fsimage_0000000000000085000* /backup/seen_txid .
Defensive patterns

Strategy: validation

Validate before calling

RandomAccessFile raf = new RandomAccessFile(img, "r");
long len = raf.length();
if (len < 8) throw new IOException("fsimage too small: " + len);
raf.seek(len - 4);
int summaryLen = raf.readInt();
if (summaryLen <= 0 || summaryLen > len) {
  throw new IOException("fsimage tail invalid (truncated?): " + summaryLen);
}

Try / catch

catch IOException from FSImageUtil.loadSummary — 'Negative length of the file' means the copy is incomplete; re-transfer from the source and re-verify md5 rather than retrying the same bytes.

Prevention

When it happens

Trigger: FSImageUtil.loadSummary() on a file whose final 4 bytes decode to a non-positive int: truncated fsimage, an empty/partial copy, or random bytes at the tail.

Common situations: NameNode killed or the disk full during saveNamespace; partial scp/cp of fsimage; image written to a full or flaky NFS volume.

Related errors


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