apache/druid · error · IllegalStateException

Corrupt frame file: frame [%,d] location out of range

Error message

Corrupt frame file: frame [%,d] location out of range

What it means

getFrameEndPosition reads a frame's end offset from the footer and bounds-checks it against the frame-data region of the file. An out-of-range value (negative or beyond the data region) means the footer's frame pointer table is corrupt, so it throws instead of returning a bogus offset.

Solutions

  1. Regenerate the frame file from the producing job; the pointer table cannot be trusted or reconstructed safely.
  2. Re-read the file from a different replica/deep-storage location if available.
  3. Check the storage layer (disk errors, S3 integrity) if corruption recurs.
  4. Validate the whole file (footer checksum, open()) before iterating frames to fail earlier with a clearer error.

Example fix

// before
long pos = footer.startByte(frameNumber); // ISE for corrupt table
// after
// open() already validates the footer checksum; prefer fully validating first
try (FrameFile.Entry entry = FrameFile.open(file, maxMmapSize)) {
  long pos = entry.footer().startByte(frameNumber);
} catch (IllegalStateException e) {
  regenerateFrameFile(file); // corrupt pointer table: rebuild
}
Defensive patterns

Strategy: validation

Validate before calling

FrameFile.Entry entry = FrameFile.open(file, maxMmapSize); // validates footer first
FrameFileFooter footer = entry.footer();
if (frameNumber < 0 || frameNumber >= footer.getNumFrames()) {
  throw new IndexOutOfBoundsException("frameNumber=" + frameNumber);
}

Type guard

static boolean isValidFrameIndex(FrameFileFooter footer, int frameNumber) {
  return frameNumber >= 0 && frameNumber < footer.getNumFrames();
}

Try / catch

try {
  long end = footer.endByte(frameNumber);
} catch (IllegalStateException e) {
  if (e.getMessage().contains("location out of range")) {
    // corrupt pointer table: switch to a replica or regenerate
    throw new IllegalStateException("Frame pointers corrupt: " + file, e);
  }
  throw e;
}

Prevention

When it happens

Trigger: Calling getFrameEndPosition (directly or via startByte/endByte) on a frame file whose footer frame-end table was corrupted, truncated, or written inconsistently — the stored long is negative or exceeds fileLength - footerSize.

Common situations: Reading a frame file damaged by a partial write or crash; accessing a specific frame index in a file that failed footer validation edge cases; disk corruption on deep storage.

Understand the failure class

Background: Checksum mismatch errors: "checksum verification failed", "digest mismatch", "expected vs actual checksum" — what they mean and how to fix them — this error's family across 41 libraries.

Related errors


AI-assisted analysis of apache/druid@9b90983fd2 (2026-09-07). Data as JSON: /api/errors/d014d95962ec368d. Report an issue: GitHub.

Appendix: source

Thrown at processing/src/main/java/org/apache/druid/frame/file/FrameFileFooter.java:112

  }

  /**
   * Get the last byte for the frame specified. The byte number is offsetted from the frame file start and is exclusive.
   * @param frameNumber the id of the frame to get the end position for
   * @return a long exclusive index representing the frame end
   */
  public long getFrameEndPosition(final int frameNumber)
  {
    assert frameNumber >= 0 && frameNumber < numFrames;

    final long frameEndPointerPosition =
        footerMemory.getCapacity() - FrameFileWriter.TRAILER_LENGTH - (long) (numFrames - frameNumber) * Long.BYTES;

    final long frameEndPosition = footerMemory.getLong(frameEndPointerPosition);

    // Bounds check: protect against possibly-corrupt data.
    if (frameEndPosition < 0 || frameEndPosition > frameFileLength - footerMemory.getCapacity()) {
      throw new ISE("Corrupt frame file: frame [%,d] location out of range", frameNumber);
    }

    return frameEndPosition;
  }

  public int getNumFrames()
  {
    return numFrames;
  }

  public int getNumPartitions()
  {
    return numPartitions;
  }
}

View on GitHub (pinned to 9b90983fd2)