{"record":{"id":"1e710a0be1ff7c8d","repo":"apache/druid","slug":"invalid-segment-dir-s-can-t-find-either-of-ver","errorCode":null,"errorMessage":"Invalid segment dir [%s]. Can't find either of version.bin or index.drd.","messagePattern":"Invalid segment dir \\[(.+?)\\]\\. Can't find either of version\\.bin or index\\.drd\\.","errorType":"exception","errorClass":"IOException","httpStatus":null,"severity":"error","filePath":"processing/src/main/java/org/apache/druid/segment/SegmentUtils.java","lineNumber":90,"sourceCode":"\n    final File indexFile = new File(inDir, \"index.drd\");\n    int version;\n    if (indexFile.exists()) {\n      try (InputStream in = new FileInputStream(indexFile)) {\n        version = in.read();\n      }\n      return version;\n    }\n\n    final File v10IndexFile = new File(inDir, IndexIO.V10_FILE_NAME);\n    if (v10IndexFile.exists()) {\n      try (InputStream in = new FileInputStream(v10IndexFile)) {\n        version = in.read();\n      }\n      return version;\n    }\n\n    throw new IOE(\"Invalid segment dir [%s]. Can't find either of version.bin or index.drd.\", inDir);\n  }\n\n  /**\n   * Returns an object whose toString() returns a String with identifiers of the given segments, comma-separated. Useful\n   * for log messages. Not useful for anything else, because this doesn't take special effort to escape commas that\n   * occur in identifiers (not common, but could potentially occur in a datasource name).\n   */\n  @Nullable\n  public static Object commaSeparatedIdentifiers(@Nullable final Collection<DataSegment> segments)\n  {\n    if (segments == null || segments.isEmpty()) {\n      return null;\n    }\n    // Lazy, to avoid preliminary string creation if logging level is turned off\n    return Collections2.transform(segments, DataSegment::getId);\n  }\n\n  public static Map<Interval, List<DataSegment>> groupSegmentsByInterval(Collection<DataSegment> segments)","sourceCodeStart":72,"sourceCodeEnd":108,"githubUrl":"https://github.com/apache/druid/blob/9b90983fd291f26935af934383ce360473179e4d/processing/src/main/java/org/apache/druid/segment/SegmentUtils.java#L72-L108","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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"],"exampleFix":"// before\nint version = SegmentUtils.getVersionFromDir(new File(configuredDir));\n// after\nFile dir = new File(configuredDir);\nif (!new File(dir, \"index.drd\").exists() && !new File(dir, \"version.bin\").exists()) {\n  throw new IOE(\"Not a segment dir [%s]; re-fetch from deep storage\", dir);\n}\nint version = SegmentUtils.getVersionFromDir(dir);","handlingStrategy":"validation","validationCode":"File dir = new File(path);\nif (!dir.isDirectory() || !(new File(dir, \"version.bin\").exists() || new File(dir, \"index.drd\").exists())) {\n  throw new FileNotFoundException(path + \" is not a valid segment dir\");\n}","typeGuard":null,"tryCatchPattern":"try {\n  int v = SegmentUtils.getVersionFromDir(dir);\n} catch (IOException e) {\n  log.error(e, \"Invalid segment dir %s; refetching from deep storage\", dir);\n  reFetchSegment(segmentId);\n}","preventionTips":["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"],"tags":["segment","filesystem","corruption"],"backgroundTag":"file-not-found","analyzedSha":"9b90983fd291f26935af934383ce360473179e4d","analyzedAt":"2026-09-07T13:32:30.957Z","contentChangedAt":"2026-09-07T13:32:30.957Z","schemaVersion":2},"datasetVersion":"2026-09-17T15:17:12.973Z"}