apache/druid · critical · RE

Unknown version %s

Error message

Unknown version %s

What it means

CompressedComplexColumnSupplier.read dispatches on a stored column format version (e.g. VERSION 3/4). If the version byte in the column is not one it knows, it throws this RE. This means the segment column was written by an incompatible (usually newer or non-Druid) writer and cannot be read by this Druid version.

Source

Thrown at processing/src/main/java/org/apache/druid/segment/serde/CompressedComplexColumnSupplier.java:96

        if (metadata.hasNulls()) {
          columnBuilder.setHasNulls(true);
          final ByteBuffer nullIndexBuffer = NestedCommonFormatColumnPartSerde.loadInternalFile(
              mapper,
              metadata.getFileNameBase(),
              ColumnSerializerUtils.NULL_BITMAP_FILE_NAME
          );
          nullValues = metadata.getBitmapSerdeFactory().getObjectStrategy().fromByteBufferWithSize(nullIndexBuffer);
        } else {
          nullValues = metadata.getBitmapSerdeFactory().getBitmapFactory().makeEmptyImmutableBitmap();
        }

        return new CompressedComplexColumnSupplier<>(typeName, objectStrategy, compressedColumnSupplier, nullValues);
      }
      catch (IOException ex) {
        throw new RE(ex, "Failed to deserialize V%s column.", version);
      }
    }
    throw new RE("Unknown version " + version);
  }

  private final String typeName;
  private final ObjectStrategy<T> objectStrategy;
  private final CompressedVariableSizedBlobColumnSupplier compressedColumnSupplier;
  private final ImmutableBitmap nullValues;

  private CompressedComplexColumnSupplier(
      String typeName,
      ObjectStrategy<T> objectStrategy,
      CompressedVariableSizedBlobColumnSupplier compressedColumnSupplier,
      ImmutableBitmap nullValues
  )
  {
    this.typeName = typeName;
    this.objectStrategy = objectStrategy;
    this.compressedColumnSupplier = compressedColumnSupplier;
    this.nullValues = nullValues;

View on GitHub (pinned to 9b90983fd2)

Solutions

  1. Upgrade the Druid cluster to a version that supports the segment's column version (match the version that wrote the segments).
  2. Do not downgrade Druid below the version that produced existing segments; re-ingest into the older format if downgrade is required.
  3. Ensure writer and reader extension versions for the complex type match across the cluster.
  4. If a single segment is suspect (corruption), restore or re-ingest that segment.
Defensive patterns

Strategy: validation

Validate before calling

// pin the cluster to one Druid version and verify before upgrade/downgrade:
// segment version compatibility is documented per Druid release; never roll back below the writer version.

Try / catch

try {
    return segment.getColumn(columnName);
} catch (RE e) {
    if (e.getMessage().startsWith("Unknown version")) {
        throw new IllegalStateException("Druid version too old for segment " + segmentId + "; upgrade required", e);
    }
    throw e;
}

Prevention

When it happens

Trigger: Reading a compressed complex column whose serialized version byte is neither of the values handled by read() — typically a segment written by a newer Druid version or corrupted data where the version field is garbage.

Common situations: Downgrading Druid: running an older Druid version against segments written by a newer version; extension version mismatch between writer and reader for custom complex types; segment file corruption flipping the version byte.

Related errors


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