apache/seatunnel · error · IllegalArgumentException
Cannot convert to BigDecimal:
Error message
Cannot convert to BigDecimal:
What it means
Iceberg RowConverter throws this when a field value cannot be converted to the target decimal type. It accepts Number (double) and String inputs; anything else reaches the else branch. The class name of the offending value is appended to the message to help identify the source of the bad data.
Solutions
- Inspect the class name in the message and trace which upstream column produced that type.
- Ensure the SeaTunnel source emits Number or String for decimal fields; configure source type mapping accordingly.
- Add a transform to cast the column (e.g. CAST to DECIMAL) before the Iceberg sink.
- If the value is genuinely non-numeric, fix data quality at the source or drop/coerce the field.
Example fix
// before Object v = rowData.getField(2); // byte[] from upstream // after Object v = new String((byte[]) rowData.getField(2)); // or CAST in a transform so converter gets Number/String
Defensive patterns
Strategy: type-guard
Validate before calling
if (!(v instanceof Number) && !(v instanceof String)) throw new IllegalArgumentException("decimal column must be Number/String, got " + (v == null ? "null" : v.getClass().getName())); Type guard
boolean isDecimalConvertible(Object v) { return v instanceof Number || v instanceof String; } Try / catch
try { sink.write(row); } catch (IllegalArgumentException e) { if (e.getMessage().startsWith("Cannot convert to BigDecimal")) { log.error("Bad decimal value: {}", e.getMessage()); /* skip or DLQ row */ } else throw e; } Prevention
- Map source decimal columns to SeaTunnel DecimalType or StringType
- CAST non-numeric columns in a transform before the Iceberg sink
- Log field classes during initial schema validation of new pipelines
When it happens
Trigger: convertDecimal receives a value that is neither Number nor String while mapping a SeaTunnel row to an Iceberg DECIMAL column, e.g. a Boolean, byte[], or a null-typed boxed object produced upstream.
Common situations: Upstream source emits decimal columns as an unexpected Java type (e.g. CDC deserialization yields byte[] or BigDecimal handled by a different branch); schema mismatch where a string-typed SeaTunnel column maps to a decimal Iceberg column but a nested type slips through.
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
- Cannot convert date:
- Cannot convert time:
- Cannot convert timestamp: , type:
- Cannot convert to binary:
- Cannot convert to boolean:
AI-assisted analysis of apache/seatunnel@cf67b549a7 (2026-09-10).
Data as JSON: /api/errors/b9afc80ad9156f42.
Report an issue: GitHub.
Appendix: source
Thrown at seatunnel-connectors-v2/connector-iceberg/src/main/java/org/apache/seatunnel/connectors/seatunnel/iceberg/data/RowConverter.java:334
"Cannot convert to double: " + value.getClass().getName());
}
protected BigDecimal convertDecimal(Object value, Types.DecimalType type) {
BigDecimal bigDecimal;
if (value instanceof BigDecimal) {
bigDecimal = (BigDecimal) value;
} else if (value instanceof Number) {
Number num = (Number) value;
Double dbl = num.doubleValue();
if (dbl.equals(Math.floor(dbl))) {
bigDecimal = BigDecimal.valueOf(num.longValue());
} else {
bigDecimal = BigDecimal.valueOf(dbl);
}
} else if (value instanceof String) {
bigDecimal = new BigDecimal((String) value);
} else {
throw new IllegalArgumentException(
"Cannot convert to BigDecimal: " + value.getClass().getName());
}
return bigDecimal.setScale(type.scale(), RoundingMode.HALF_UP);
}
protected boolean convertBoolean(Object value) {
if (value instanceof Boolean) {
return (boolean) value;
} else if (value instanceof String) {
return Boolean.parseBoolean((String) value);
}
throw new IllegalArgumentException(
"Cannot convert to boolean: " + value.getClass().getName());
}
protected String convertString(Object value) {
try {
if (value instanceof String) {View on GitHub (pinned to cf67b549a7)