apache/druid · error · IllegalArgumentException
Expected version[9], got[%d]
Error message
Expected version[9], got[%d]
What it means
The v9 segment mapper (DefaultMapper) reads version.bin and requires exactly V9_VERSION (9). Any other integer means the directory is not a v9 segment — usually a v8 segment or corrupt version file — so loading is rejected with IAE.
Source
Thrown at processing/src/main/java/org/apache/druid/segment/IndexIO.java:574
static class V9IndexLoader implements IndexLoader
{
private final ColumnConfig columnConfig;
V9IndexLoader(ColumnConfig columnConfig)
{
this.columnConfig = columnConfig;
}
@Override
public QueryableIndex load(File inDir, ObjectMapper mapper, boolean lazy, SegmentLazyLoadFailCallback loadFailed)
throws IOException
{
log.debug("Mapping v9 index[%s]", inDir);
long startTime = System.currentTimeMillis();
final int theVersion = Ints.fromByteArray(Files.toByteArray(new File(inDir, "version.bin")));
if (theVersion != V9_VERSION) {
throw new IAE("Expected version[9], got[%d]", theVersion);
}
SmooshedFileMapper smooshedFiles = Smoosh.map(inDir);
ByteBuffer indexBuffer = smooshedFiles.mapFile("index.drd");
/**
* Index.drd should consist of the segment version, the columns and dimensions of the segment as generic
* indexes, the interval start and end millis as longs (in 16 bytes), and a bitmap index type.
*/
final GenericIndexed<String> nonNullCols = GenericIndexed.read(
indexBuffer,
GenericIndexed.STRING_STRATEGY,
smooshedFiles
);
final GenericIndexed<String> nonNullDims = GenericIndexed.read(
indexBuffer,
GenericIndexed.STRING_STRATEGY,
smooshedFilesView on GitHub (pinned to 9b90983fd2)
Solutions
- Check version.bin contents and route v8 segments through the legacy loader or convert them to v9
- Re-download the segment from deep storage if version.bin is truncated or corrupt
- Upgrade/downgrade so the Druid version supports the segment's format version, or re-ingest the data
Example fix
// before
IndexableAdapter adapter = IndexIO.mapIO(segmentDir); // assumes v9
// after
byte[] v = Files.toByteArray(new File(segmentDir, "version.bin"));
if (Ints.fromByteArray(v) != IndexIO.V9_VERSION) {
// convert legacy segment before loading
segmentDir = convertToV9(segmentDir);
}
IndexableAdapter adapter = IndexIO.mapIO(segmentDir); Defensive patterns
Strategy: try-catch
Validate before calling
final int version = Ints.fromByteArray(Files.toByteArray(new File(inDir, "version.bin")));
if (version != IndexIO.V9_VERSION) {
throw new IllegalStateException("Segment " + inDir + " is version " + version + ", expected 9");
} Try / catch
try {
indexIO.mapDir(inDir, config, mapper, factoryMap, loaderConfig);
} catch (IAE e) {
if (e.getMessage().contains("Expected version[9]")) {
// convert legacy segment or abort loading with clear message
}
} Prevention
- Convert v8 segments to v9 before loading with modern Druid
- Validate version.bin exists and parses after segment restore
- Keep Druid version aligned with the segment format version in deep storage
When it happens
Trigger: IndexIO.mapDir (v9 path) invoked on a directory whose version.bin contains 8 (legacy), another future version, or garbage from a truncated write.
Common situations: Pointing a modern loader at legacy v8 segments without running the v8->v9 conversion; interrupted segment writes leaving an empty/partial version.bin; restoring segments from incompatible Druid versions.
Related errors
AI-assisted analysis of apache/druid@9b90983fd2 (2026-09-07).
Data as JSON: /api/errors/d52a096e1bedcc20.
Report an issue: GitHub.