apache/iceberg · error · IllegalArgumentException

Unsupported primitive type for decimal: <type>

Error message

Unsupported primitive type for decimal: <type>

What it means

Thrown by ParquetConversions.convertValue when converting a Parquet value to an Iceberg DECIMAL value and the Parquet column's primitive type is neither INT32, INT64, FIXED_LEN_BYTE_ARRAY nor BINARY. Decimal values in Parquet must be stored in one of those physical types, so any other primitive reaching this converter is invalid.

Source

Thrown at parquet/src/main/java/org/apache/iceberg/parquet/ParquetConversions.java:67

      case STRING:
        return (T) ((Binary) value).toStringUsingUTF8();
      case UUID:
        return (T) UUIDUtil.convert(((Binary) value).toByteBuffer());
      case FIXED:
      case BINARY:
        return (T) ((Binary) value).toByteBuffer();
      case DECIMAL:
        int scale =
            ((DecimalLogicalTypeAnnotation) parquetType.getLogicalTypeAnnotation()).getScale();
        switch (parquetType.getPrimitiveTypeName()) {
          case INT32:
          case INT64:
            return (T) BigDecimal.valueOf(((Number) value).longValue(), scale);
          case FIXED_LEN_BYTE_ARRAY:
          case BINARY:
            return (T) new BigDecimal(new BigInteger(((Binary) value).getBytes()), scale);
          default:
            throw new IllegalArgumentException(
                "Unsupported primitive type for decimal: " + parquetType.getPrimitiveTypeName());
        }
      default:
        throw new IllegalArgumentException("Unsupported primitive type: " + type);
    }
  }

  static Function<Object, Object> converterFromParquet(
      PrimitiveType parquetType, Type icebergType) {
    Function<Object, Object> fromParquet = converterFromParquet(parquetType);
    if (icebergType != null) {
      if (icebergType.typeId() == Type.TypeID.LONG
          && parquetType.getPrimitiveTypeName() == PrimitiveType.PrimitiveTypeName.INT32) {
        return value -> ((Integer) fromParquet.apply(value)).longValue();
      } else if (icebergType.typeId() == Type.TypeID.DOUBLE
          && parquetType.getPrimitiveTypeName() == PrimitiveType.PrimitiveTypeName.FLOAT) {
        return value -> ((Float) fromParquet.apply(value)).doubleValue();
      } else if (icebergType.typeId() == Type.TypeID.UUID) {

View on GitHub (pinned to 86d9c8fc54)

Solutions

  1. Rewrite/re-encode the Parquet file so the decimal column uses INT32/INT64/FIXED_LEN_BYTE_ARRAY/BINARY as appropriate for precision.
  2. Fix the Parquet schema at write time to declare the correct physical type for the decimal logical type.
  3. If you control the read path, use converterFromParquet only with compatible primitive types and guard the type beforehand.

Example fix

// before
Types.DecimalType.of(38, 10) backed by a FLOAT Parquet column
// after
declare the column in Parquet as BINARY (DECIMAL logical type) or INT64 and re-encode the data
Defensive patterns

Strategy: validation

Validate before calling

org.apache.parquet.schema.PrimitiveType pt = parquetType.asPrimitiveType();
switch (pt.getPrimitiveTypeName()) {
  case INT32: case INT64: case FIXED_LEN_BYTE_ARRAY: case BINARY: break;
  default: throw new IllegalStateException("Decimal column has invalid physical type: " + pt.getPrimitiveTypeName());
}

Type guard

boolean isDecimalSafe(PrimitiveType pt) {
  return pt.getPrimitiveTypeName() == PrimitiveType.PrimitiveTypeName.INT32
      || pt.getPrimitiveTypeName() == PrimitiveType.PrimitiveTypeName.INT64
      || pt.getPrimitiveTypeName() == PrimitiveType.PrimitiveTypeName.FIXED_LEN_BYTE_ARRAY
      || pt.getPrimitiveTypeName() == PrimitiveType.PrimitiveTypeName.BINARY;
}

Try / catch

try {
  Object v = ParquetConversions.convertValue(parquetType, icebergType, ...);
} catch (IllegalArgumentException e) {
  throw new SchemaParseException("Parquet decimal column has incompatible physical type", e);
}

Prevention

When it happens

Trigger: Reading data whose Parquet schema declares a decimal logical type on an unexpected physical primitive (e.g. a corrupted or handcrafted schema), calling convertValue directly with a mismatched parquetType.

Common situations: Hand-written or third-party Parquet files with nonstandard decimal encodings; schema mismatch between the writer and reader; buggy custom writer libraries.

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


AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12). Data as JSON: /api/errors/5ec0c2a089cd0fca. Report an issue: GitHub.