apache/druid · error · IllegalArgumentException
Expected instance of %s, got %s
Error message
Expected instance of %s, got %s
What it means
KafkaDataSourceMetadata.compareTo() only knows how to compare against another instance of the same concrete class; comparing against a different DataSourceMetadata subclass throws IAE('Expected instance of %s, got %s').
Source
Thrown at extensions-core/kafka-indexing-service/src/main/java/org/apache/druid/indexing/kafka/KafkaDataSourceMetadata.java:108
return this;
}
}
@Override
protected SeekableStreamDataSourceMetadata<KafkaTopicPartition, Long> createConcreteDataSourceMetaData(
SeekableStreamSequenceNumbers<KafkaTopicPartition, Long> seekableStreamSequenceNumbers
)
{
return new KafkaDataSourceMetadata(seekableStreamSequenceNumbers, getBoundedStreamConfig());
}
@Override
// This method is to compare KafkaDataSourceMetadata.
// It compares this and other SeekableStreamSequenceNumbers using naturalOrder comparator.
public int compareTo(KafkaDataSourceMetadata other)
{
if (!getClass().equals(other.getClass())) {
throw new IAE(
"Expected instance of %s, got %s",
this.getClass().getName(),
other.getClass().getName()
);
}
return getSeekableStreamSequenceNumbers().compareTo(other.getSeekableStreamSequenceNumbers(), Comparator.naturalOrder());
}
@Override
public boolean matches(DataSourceMetadata other)
{
if (!getClass().equals(other.getClass())) {
return false;
}
KafkaDataSourceMetadata thisPlusOther = (KafkaDataSourceMetadata) plus(other);
if (thisPlusOther.equals(other.plus(this))) {
return true;
}View on GitHub (pinned to 9b90983fd2)
Solutions
- Ensure only one concrete KafkaDataSourceMetadata class is used for a datasource; migrate/merge stored metadata
- Do not compare metadata objects of different datasources/types
- If comparing arbitrary metadata, use equals or type-check first
Example fix
// before
metadataA.compareTo(metadataB); // may be a different subclass
// after
if (metadataA.getClass().equals(metadataB.getClass())) { metadataA.compareTo(metadataB); } Defensive patterns
Strategy: type-guard
Validate before calling
if (a.getClass() != b.getClass()) throw new IllegalArgumentException("cannot compare different metadata types"); Type guard
boolean comparable(org.apache.druid.metadata.DateWeightedVector... ) {} // no; use: boolean isSameClass(DataSourceMetadata a, DataSourceMetadata b) { return a.getClass().equals(b.getClass()); } Try / catch
try {
return a.compareTo(b);
} catch (IllegalArgumentException e) {
if (e.getMessage().startsWith("Expected instance of")) { return 0; /* or handle as incomparable */ }
throw e;
} Prevention
- Keep one metadata class per datasource
- Clean up metadata after version migrations
- Type-check before comparing DataSourceMetadata objects
When it happens
Trigger: Calling compareTo (e.g. during metadata segment sorting/merging in coordinator/handoff paths) with a KafkaDataSourceMetadata of a different concrete class or another datasource metadata type.
Common situations: Mixing datasource metadata types (e.g. legacy vs current classes after a version upgrade) for the same datasource in metadata storage.
Understand the failure class
Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.
Related errors
- Unknwon types [%s] and [%s]
- Expected a number or an instance of DDSketch, but received [
- Expected a number or an instance of DDSketch, but received [
- Cannot deserialize type[%s] to an RoaringBitmap64Counter:
- Object cannot be deserialized to a Spectator Histogram
AI-assisted analysis of apache/druid@9b90983fd2 (2026-09-07).
Data as JSON: /api/errors/f1e092b579c22a25.
Report an issue: GitHub.