apache/druid · error · IOException

Invalid segment dir [ ]. Can't find either of version.bin…

Error message

Invalid segment dir [%s]. Can't find either of version.bin or index.drd.

What it means

SegmentUtils.getVersionFromDir determines a segment directory's format version by reading version.bin (or index.drd). If neither marker file exists in the directory, it throws an IOException declaring the segment dir invalid. This usually means the path is not a real Druid segment directory or it is corrupted/incomplete.

Solutions

  1. Verify the directory path actually contains a segment (look for version.bin or index.drd)
  2. Re-download/restore the segment from deep storage
  3. Re-run the ingestion task to regenerate the segment if deep storage copy is also damaged
  4. Clean the local segment cache so the segment is fetched anew

Example fix

// before
int version = SegmentUtils.getVersionFromDir(new File(configuredDir));
// after
File dir = new File(configuredDir);
if (!new File(dir, "index.drd").exists() && !new File(dir, "version.bin").exists()) {
  throw new IOE("Not a segment dir [%s]; re-fetch from deep storage", dir);
}
int version = SegmentUtils.getVersionFromDir(dir);
Defensive patterns

Strategy: validation

Validate before calling

File dir = new File(path);
if (!dir.isDirectory() || !(new File(dir, "version.bin").exists() || new File(dir, "index.drd").exists())) {
  throw new FileNotFoundException(path + " is not a valid segment dir");
}

Try / catch

try {
  int v = SegmentUtils.getVersionFromDir(dir);
} catch (IOException e) {
  log.error(e, "Invalid segment dir %s; refetching from deep storage", dir);
  reFetchSegment(segmentId);
}

Prevention

When it happens

Trigger: Calling getVersionFromDir on a directory missing both version.bin and index.drd — e.g. a partially downloaded/copied segment, a wrong path passed to segment-loading code, or a deep-storage restore that failed midway.

Common situations: Segment restore/interrupt during historical loading; pointing druid.segment.dir or local cache at a wrong directory; manually moving segment files without their metadata; disk corruption or truncation.

Understand the failure class

Background: "File not found" and ENOENT errors: why libraries can't find a file that should exist — this error's family across 50 libraries.

Related errors


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

Appendix: source

Thrown at processing/src/main/java/org/apache/druid/segment/SegmentUtils.java:90

    final File indexFile = new File(inDir, "index.drd");
    int version;
    if (indexFile.exists()) {
      try (InputStream in = new FileInputStream(indexFile)) {
        version = in.read();
      }
      return version;
    }

    final File v10IndexFile = new File(inDir, IndexIO.V10_FILE_NAME);
    if (v10IndexFile.exists()) {
      try (InputStream in = new FileInputStream(v10IndexFile)) {
        version = in.read();
      }
      return version;
    }

    throw new IOE("Invalid segment dir [%s]. Can't find either of version.bin or index.drd.", inDir);
  }

  /**
   * Returns an object whose toString() returns a String with identifiers of the given segments, comma-separated. Useful
   * for log messages. Not useful for anything else, because this doesn't take special effort to escape commas that
   * occur in identifiers (not common, but could potentially occur in a datasource name).
   */
  @Nullable
  public static Object commaSeparatedIdentifiers(@Nullable final Collection<DataSegment> segments)
  {
    if (segments == null || segments.isEmpty()) {
      return null;
    }
    // Lazy, to avoid preliminary string creation if logging level is turned off
    return Collections2.transform(segments, DataSegment::getId);
  }

  public static Map<Interval, List<DataSegment>> groupSegmentsByInterval(Collection<DataSegment> segments)

View on GitHub (pinned to 9b90983fd2)