apache/iceberg · error · UnsupportedOperationException

Unsupported base type for decimal: ${primitiveTypeName}

Error message

Unsupported base type for decimal: ${primitiveTypeName}

What it means

LogicalTypeWriterBuilder.visit(DecimalLogicalTypeAnnotation) maps decimal columns to writers depending on the underlying physical type: INT32/INT64 for smaller decimals, BINARY/FIXED_LEN_BYTE_ARRAY for fixed decimals. Any other base type cannot store a decimal, so UnsupportedOperationException is thrown.

Source

Thrown at flink/v1.20/flink/src/main/java/org/apache/iceberg/flink/data/FlinkParquetWriters.java:231

      return Optional.of(strings(desc));
    }

    @Override
    public Optional<ParquetValueWriter<?>> visit(DecimalLogicalTypeAnnotation decimal) {
      ParquetValueWriter<DecimalData> writer;
      switch (desc.getPrimitiveType().getPrimitiveTypeName()) {
        case INT32:
          writer = decimalAsInteger(desc, decimal.getPrecision(), decimal.getScale());
          break;
        case INT64:
          writer = decimalAsLong(desc, decimal.getPrecision(), decimal.getScale());
          break;
        case BINARY:
        case FIXED_LEN_BYTE_ARRAY:
          writer = decimalAsFixed(desc, decimal.getPrecision(), decimal.getScale());
          break;
        default:
          throw new UnsupportedOperationException(
              "Unsupported base type for decimal: "
                  + desc.getPrimitiveType().getPrimitiveTypeName());
      }
      return Optional.of(writer);
    }

    @Override
    public Optional<ParquetValueWriter<?>> visit(DateLogicalTypeAnnotation dates) {
      return Optional.of(ints(flinkType, desc));
    }

    @Override
    public Optional<ParquetValueWriter<?>> visit(TimeLogicalTypeAnnotation times) {
      Preconditions.checkArgument(
          LogicalTypeAnnotation.TimeUnit.MICROS.equals(times.getUnit()),
          "Cannot write time in %s, only MICROS is supported",
          times.getUnit());
      return Optional.of(timeMicros(desc));

View on GitHub (pinned to 86d9c8fc54)

Solutions

  1. Rewrite the source Parquet so decimal columns use a valid base type (int32, int64, binary, or fixed_len_byte_array).
  2. Check the producing system's decimal-to-physical mapping and fix its configuration (e.g. spark.sql.parquet.writeLegacyFormat or equivalent).
  3. Cast the column to a supported type (e.g. string or double) upstream if the decimal annotation is not required.
  4. Verify the file with parquet-tools to confirm the actual physical type before assuming an Iceberg bug.

Example fix

// before: parquet column: double col with DECIMAL(10,2) annotation
// after: rewrite with a valid base type
// Schema: required int64 col (DECIMAL(10,2))
Defensive patterns

Strategy: validation

Validate before calling

for (Type f : parquetSchema.getFields()) {
  if (f.isPrimitive()) {
    LogicalTypeAnnotation ann = ((PrimitiveType) f).getLogicalTypeAnnotation();
    PrimitiveTypeName base = ((PrimitiveType) f).getPrimitiveTypeName();
    if (ann instanceof DecimalLogicalTypeAnnotation &&
        !(base == INT32 || base == INT64 || base == BINARY || base == FIXED_LEN_BYTE_ARRAY)) {
      throw new IllegalArgumentException("invalid decimal base: " + base);
    }
  }
}

Try / catch

try {
  writer = ...build();
} catch (UnsupportedOperationException e) {
  if (e.getMessage().contains("Unsupported base type for decimal")) {
    // rewrite source data with valid decimal physical type
  }
}

Prevention

When it happens

Trigger: A Parquet column annotated as decimal but physically stored as FLOAT, DOUBLE, INT96, or BOOLEAN - a combination the switch does not handle - triggering the default branch.

Common situations: Files written by non-conforming producers storing decimals on floating-point or legacy INT96 columns; hand-edited Parquet schemas; converting data from systems with loose decimal-to-physical-type mappings.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


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