apache/druid · error · IncompatibleTypeException
Incompatible types: %s and %s
Error message
Incompatible types: %s and %s
What it means
ColumnType.leastRestrictiveType computes the common supertype of two column types; when neither is null and neither is nested-data-compatible complex, incompatible types (e.g. STRING vs LONG) raise Types.IncompatibleTypeException. It is thrown while reconciling types across operators, functions, or auto-detected inputs.
Source
Thrown at processing/src/main/java/org/apache/druid/segment/column/ColumnType.java:178
*/
@Nullable
public static ColumnType leastRestrictiveType(@Nullable ColumnType type, @Nullable ColumnType other) throws Types.IncompatibleTypeException
{
if (type == null) {
return other;
}
if (other == null) {
return type;
}
if (type.is(ValueType.COMPLEX) && other.is(ValueType.COMPLEX)) {
if (type.getComplexTypeName() == null) {
return other;
}
if (other.getComplexTypeName() == null) {
return type;
}
if (!Objects.equals(type, other)) {
throw new Types.IncompatibleTypeException(type, other);
}
return type;
}
// if either is nested data, use nested data, otherwise error
if (type.is(ValueType.COMPLEX) || other.is(ValueType.COMPLEX)) {
if (ColumnType.NESTED_DATA.equals(type) || ColumnType.NESTED_DATA.equals(other)) {
return ColumnType.NESTED_DATA;
}
throw new Types.IncompatibleTypeException(type, other);
}
// arrays convert based on least restrictive element type
if (type.isArray()) {
if (other.equals(type.getElementType())) {
return type;
}
final ColumnType commonElementType;
// commonElementType cannot be null if we got this far, we always return a value unless both args are nullView on GitHub (pinned to 9b90983fd2)
Solutions
- Add explicit CASTs so both sides share a type: CAST(col AS BIGINT) or CAST(col AS VARCHAR)
- Fix the schema/type of one input column (re-index or correct ingestion type)
- If a complex (COMPLEX<name>) column is involved, ensure both sides use the same complex type name or cast to a primitive
Example fix
// before // WHERE stringCol = longCol -> Incompatible types: STRING and LONG // after // WHERE stringCol = CAST(longCol AS VARCHAR)
Defensive patterns
Strategy: validation
Validate before calling
ColumnType a = sqlTypeNameOf(left), b = sqlTypeNameOf(right);
try { ColumnType.common = ColumnType.leastRestrictiveType(a, b); } catch (IncompatibleTypeException e) { /* require explicit CAST */ } Try / catch
try { common = ColumnType.leastRestrictiveType(t1, t2); } catch (IncompatibleTypeException e) { throw new ValidationException("add a CAST between " + t1 + " and " + t2); } Prevention
- Add explicit CASTs whenever comparing/joining across types
- Check column types via INFORMATION_SCHEMA/segment metadata before writing queries
- Keep join key types identical across datasources
When it happens
Trigger: leastRestrictiveType(string, long) or similar, invoked from autoDetect, operator/function type resolution, or recursive calls, when no common supertype exists.
Common situations: SQL queries joining/comparing columns of incompatible types (string vs number, different complex types); COALESCE/CASE branches with mismatched types; schema drift between tables in a join.
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
- Unknown
- Cannot deserialize type[%s] to an RoaringBitmap64Counter:
- Cannot translate sqlTypeName[%s] to Druid type for field[%s]
- Expected a number or an instance of MergingDigest, but recei
- Cannot translate sqlTypeName[%s] to Druid type for field[%s]
AI-assisted analysis of apache/druid@9b90983fd2 (2026-09-07).
Data as JSON: /api/errors/f0db2a00d48291f8.
Report an issue: GitHub.