apache/druid · error · ParseException
Cannot coerce column [%s] input to requested type [%s]
Error message
Cannot coerce column [%s] input to requested type [%s]
What it means
During auto (nested JSON) column indexing, the value read from a row is cast to the column's configured castToExpressionType. If ExprEval.castTo cannot coerce the input value (e.g. casting a non-numeric string to LONG), it throws IllegalArgumentException, which this code wraps in a Druid ParseException naming the column and requested type. This indicates ingested data does not match the declared type of the auto-type column.
Source
Thrown at processing/src/main/java/org/apache/druid/segment/AutoTypeColumnIndexer.java:180
} else {
return processAuto(dimValues);
}
}
/**
* Process values which will all be cast to {@link #castToExpressionType}. This method should not be used for
* and does not handle actual nested data structures, use {@link #processAuto(Object)} instead.
*/
private EncodedKeyComponent<StructuredData> processCast(@Nullable Object dimValues)
{
final long oldDictSizeInBytes = globalDictionary.sizeInBytes();
final int oldFieldKeySize = estimatedFieldKeySize;
ExprEval<?> eval = ExprEval.bestEffortOf(dimValues);
try {
eval = eval.castTo(castToExpressionType);
}
catch (IAE invalidCast) {
throw new ParseException(eval.asString(), invalidCast, "Cannot coerce column [%s] input to requested type [%s]", columnName, castToType);
}
FieldIndexer fieldIndexer = fieldIndexers.get(NestedPathFinder.JSON_PATH_ROOT);
if (fieldIndexer == null) {
estimatedFieldKeySize += StructuredDataProcessor.estimateStringSize(NestedPathFinder.JSON_PATH_ROOT);
fieldIndexer = new FieldIndexer(globalDictionary);
fieldIndexers.put(NestedPathFinder.JSON_PATH_ROOT, fieldIndexer);
}
StructuredDataProcessor.ProcessedValue<?> rootValue = fieldIndexer.processValue(eval);
long effectiveSizeBytes = rootValue.getSize();
// then, we add the delta of size change to the global dictionaries to account for any new space added by the
// 'raw' data
effectiveSizeBytes += (globalDictionary.sizeInBytes() - oldDictSizeInBytes);
effectiveSizeBytes += (estimatedFieldKeySize - oldFieldKeySize);
return new EncodedKeyComponent<>(StructuredData.wrap(eval.value()), effectiveSizeBytes);
}
/**View on GitHub (pinned to 9b90983fd2)
Solutions
- Fix or filter the offending input value so it matches the target type before ingestion (clean the record, or drop/transform the field).
- Use an input-format transform or expression to sanitize values (e.g. TRY_CAST-like handling) so castTo succeeds.
- If values are legitimately non-numeric, remove the cast / let auto-type detection keep them as STRING.
- Inspect the message's column name and the input string in the ParseException to locate and repair the bad record.
Example fix
// before: direct cast of raw string values to LONG fails on 'N/A'
"dimensionExclusions": [], "useSchemaDiscovery": true
// after: transform bad values before cast
"transforms": [{"type": "expression", "name": "amount",
"expression": "if(lookup(amount, 'na-map') == null, amount, null)"}] Defensive patterns
Strategy: validation
Validate before calling
Object v = row.get(column);
if (v instanceof String && target == ColumnType.LONG
&& !v.toString().matches("-?\\d+(\\.\\d+)?")) {
throw new IllegalArgumentException("value not castable to LONG: " + v);
} Type guard
boolean castable(String s, ColumnType t) {
switch (t.getType()) {
case LONG: return s.matches("-?\\d+");
case DOUBLE: return s.matches("-?\\d+(\\.\\d+)?(E-?\\d+)?");
default: return true;
}
} Try / catch
try {
indexer.processRowValsToUnsortedEncodedKeyComponent(vals, rowId, castToType);
} catch (ParseException pe) {
log.error(pe, "bad value for column %s", pe.getCause());
metrics.incrementRowOutputCountOfFailure();
} Prevention
- Validate input data against the declared column type before ingestion
- Add transforms to sanitize/normalize messy fields
- Avoid casting heterogeneous JSON fields without checks
- Monitor ParseException rates in ingestion metrics
When it happens
Trigger: Ingesting rows into an auto/NESTED_DATA column with a configured type cast (e.g. via auto-type detection or a dimension schema entry with type cast) where a value cannot be coerced — e.g. string 'abc' cast to LONG, or an object cast to a scalar type.
Common situations: Dirty input data in batch/stream ingestion; a user adds a typed dimension spec to an existing JSON column whose values are heterogeneous; changing a column's declared type after data was written with incompatible values.
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
- Unhandled type: %s
- ColumnCapacityExceededException
- Unsupported keyFormat. KafkaInputformat only supports input
- Invalid max row count:
- incrementIndexSchema cannot be null
AI-assisted analysis of apache/druid@9b90983fd2 (2026-09-07).
Data as JSON: /api/errors/35aa0680006d0cc5.
Report an issue: GitHub.