apache/druid · error · IllegalArgumentException
Unknown version[%d]
Error message
Unknown version[%d]
What it means
IndexIO.mapDir (the legacy v8 segment loader) reads the first byte of index.drd and only accepts V8_VERSION. Any other byte means the directory is not a v8 index or is corrupt, so it throws IAE. Note the check compares to V8_VERSION although the similar v9 loader messages say version 9 — for this v8 path any non-v8 version byte is rejected.
Source
Thrown at processing/src/main/java/org/apache/druid/segment/IndexIO.java:349
return new SegmentValidationException("Dim [%s] values not equal. Expected %s found %s", dimName, v1, v2);
}
public static class DefaultIndexIOHandler implements IndexIOHandler
{
private static final Logger log = new Logger(DefaultIndexIOHandler.class);
@Override
public MMappedIndex mapDir(File inDir) throws IOException
{
log.debug("Mapping v8 index[%s]", inDir);
long startTime = System.currentTimeMillis();
InputStream indexIn = null;
try {
indexIn = new FileInputStream(new File(inDir, "index.drd"));
byte theVersion = (byte) indexIn.read();
if (theVersion != V8_VERSION) {
throw new IAE("Unknown version[%d]", theVersion);
}
}
finally {
Closeables.close(indexIn, false);
}
SmooshedFileMapper smooshedFiles = Smoosh.map(inDir);
ByteBuffer indexBuffer = smooshedFiles.mapFile("index.drd");
indexBuffer.get(); // Skip the version byte
final GenericIndexed<String> availableDimensions = GenericIndexed.read(
indexBuffer,
GenericIndexed.STRING_STRATEGY,
smooshedFiles
);
final GenericIndexed<String> availableMetrics = GenericIndexed.read(
indexBuffer,
GenericIndexed.STRING_STRATEGY,View on GitHub (pinned to 9b90983fd2)
Solutions
- Verify the segment version via version.bin / SegmentUtils and route v9 segments to the v9 loader (IndexIO.DefaultMapper) instead of mapDir
- Re-download or re-unzip the segment — index.drd may be truncated or empty
- Convert the segment to the format your loader expects using IndexMerger
Example fix
// before
MMappedIndex idx = indexIO.mapDir(segmentDir); // fails on v9 dirs
// after
int version = Ints.fromByteArray(Files.toByteArray(new File(segmentDir, "version.bin")));
MMappedIndex idx = (version == IndexIO.V8_VERSION)
? indexIO.mapDir(segmentDir)
: indexIO.mapDir(segmentDir, segmentDir, segmentDir); // v9 path Defensive patterns
Strategy: try-catch
Validate before calling
try (InputStream in = new FileInputStream(new File(dir, "index.drd"))) {
byte v = (byte) in.read();
if (v != IndexIO.V8_VERSION) {
throw new IllegalStateException("Not a v8 segment (version byte " + v + ")");
}
} Try / catch
try {
MMappedIndex idx = indexIO.mapDir(inDir);
} catch (IAE e) {
if (e.getMessage().startsWith("Unknown version")) {
// fall back to the v9 loader or fail with a clear message
}
} Prevention
- Check version.bin before choosing a segment loader
- Never assume segment format when reading from deep storage; inspect metadata first
- Re-download segments whose index.drd may be truncated
When it happens
Trigger: Calling IndexIO.mapDir on a directory whose index.drd first byte is not the v8 version constant — e.g. pointing the legacy loader at a v9 segment directory, or at a truncated/corrupt index.drd (read() returning -1).
Common situations: Loading old deep-stored segments with the wrong IndexIO handler; manually unzipped/moved segment directories where index.drd is empty or from a newer format; custom tooling that walks segment dirs without checking version.bin first.
Related errors
AI-assisted analysis of apache/druid@9b90983fd2 (2026-09-07).
Data as JSON: /api/errors/77a41ec25b08ad7d.
Report an issue: GitHub.