apache/iceberg · error · java.lang.UnsupportedOperationException
Failed to read Variant %s of type %s as double
Error message
Failed to read Variant %s of type %s as double
What it means
Thrown by VariantRowDataWrapper.doubleValue: a double was requested from a variant whose primitive type is neither FLOAT nor DOUBLE (the handled cases). The message includes the variant value and its type; the consuming Flink job's expected row type disagrees with the variant's stored type.
Source
Thrown at flink/v2.1/flink/src/main/java/org/apache/iceberg/flink/data/VariantRowDataWrapper.java:273
default -> throw new UnsupportedOperationException(errMsg(variant, "int"));
};
}
private static long longValue(Variant variant) {
return switch (variant.getType()) {
case TINYINT -> variant.getByte();
case SMALLINT -> variant.getShort();
case INT -> variant.getInt();
case BIGINT -> variant.getLong();
default -> throw new UnsupportedOperationException(errMsg(variant, "long"));
};
}
private static double doubleValue(Variant variant) {
return switch (variant.getType()) {
case FLOAT -> variant.getFloat();
case DOUBLE -> variant.getDouble();
default -> throw new UnsupportedOperationException(errMsg(variant, "double"));
};
}
private static DecimalData decimalDataValue(Variant variant, DecimalType decimalType) {
return DecimalData.fromBigDecimal(
variant.getDecimal(), decimalType.getPrecision(), decimalType.getScale());
}
private static TimestampData timestampValue(Variant variant, int precision) {
return switch (variant.getType()) {
case TIMESTAMP -> TimestampData.fromLocalDateTime(variant.getDateTime());
case TIMESTAMP_LTZ -> TimestampData.fromInstant(variant.getInstant());
case BIGINT -> {
Preconditions.checkArgument(
precision >= MICROSECOND_PRECISION && precision <= NANOSECOND_PRECISION,
"Invalid precision: %s. Only micros and nanos precision are supported.",
precision);
yield precision > MICROSECOND_PRECISIONView on GitHub (pinned to 86d9c8fc54)
Solutions
- Ensure the variant's physical type is FLOAT or DOUBLE when written
- Align the RowType field to DECIMAL and read via getDecimal if variants are decimals
- Convert the value upstream to double before writing
Example fix
// before row.getDouble(5); // variant is DECIMAL -> throws // after DecimalData d = row.getDecimal(5, precision, scale);
Defensive patterns
Strategy: try-catch
Validate before calling
if (variant.getType() != Variant.Type.FLOAT
&& variant.getType() != Variant.Type.DOUBLE) { /* use decimal/other accessor */ } Type guard
boolean isFloatingPoint(Variant v) {
return v.getType() == Variant.Type.FLOAT || v.getType() == Variant.Type.DOUBLE;
} Try / catch
try { return row.getDouble(pos); }
catch (UnsupportedOperationException e) { /* fall back to getDecimal and convert */ } Prevention
- Write float/double variants for DOUBLE-typed columns
- Declare DECIMAL columns for decimal variants
- Check variant.getType() before numeric accessors
When it happens
Trigger: Calling getDouble on a VariantRowDataWrapper column whose variant is, e.g., a string or decimal rather than a float/double, or elementValue with a DOUBLE-typed field holding another variant type.
Common situations: Writers producing decimal variants for double columns; schema drift where a double column now stores numeric variants of other widths.
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
- Failed to read Variant %s of type %s as int
- Failed to read Variant %s of type %s as long
- Failed to read Variant %s of type %s as timestamp
- errMsg(variant, "int")
- errMsg(variant, "long")
AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12).
Data as JSON: /api/errors/2887fcd3900e6a25.
Report an issue: GitHub.