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
- Verify the directory path actually contains a segment (look for version.bin or index.drd)
- Re-download/restore the segment from deep storage
- Re-run the ingestion task to regenerate the segment if deep storage copy is also damaged
- 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
- Verify segment copies complete fully (atomic move/rename)
- Avoid manual edits/moves of segment directories
- Monitor segment load failures and auto refetch from deep storage
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
- Invalid table size[ ]
- Metric[ ] loaded up metric[ ] from disk. File names do…
- Actual Row count mismatch. Expected
- Attempt to add row to swapped-out sink for segment
- Bad null-marker byte, delegate class
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)