apache/iceberg · error · java.lang.UnsupportedOperationException

Unsupported base type for decimal:

Error message

Unsupported base type for decimal: 

What it means

LogicalTypeWriterBuilder.visit(DecimalLogicalTypeAnnotation) builds a decimal writer based on the underlying primitive type: BINARY and FIXED_LEN_BYTE_ARRAY use decimalAsFixed; other bases (e.g. INT32/INT64-backed decimals) are not handled and trigger UnsupportedOperationException 'Unsupported base type for decimal'.

Source

Thrown at flink/v2.3/flink/src/main/java/org/apache/iceberg/flink/data/FlinkParquetWriters.java:253

      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. Write decimals with a BINARY or FIXED_LEN_BYTE_ARRAY base type, matching the precision (FLBA typically for precision <= 38 with fixed width).
  2. Fix the schema conversion so Flink DECIMAL(p, s) maps to BINARY/FLBA with DecimalLogicalTypeAnnotation.
  3. Add support for INT32/INT64-backed decimals in visit(...) if reading such files is required.

Example fix

// before
// optional int64 ts (DECIMAL(18,2))
// after
// optional binary val (DECIMAL(18,2)) — BINARY/FLBA base with decimal annotation
Defensive patterns

Strategy: validation

Validate before calling

// java
if (annotation instanceof DecimalLogicalTypeAnnotation) {
  PrimitiveTypeName base = primitive.getPrimitiveTypeName();
  if (base != PrimitiveTypeName.BINARY && base != PrimitiveTypeName.FIXED_LEN_BYTE_ARRAY) {
    throw new IllegalArgumentException("Decimal column must use BINARY/FLBA, got " + base);
  }
}

Try / catch

// java
try {
  writer = FlinkParquetWriters.createWriter(...);
} catch (UnsupportedOperationException e) {
  // remap the decimal column to a BINARY/FLBA-backed Parquet type
}

Prevention

When it happens

Trigger: Writing a decimal column whose Parquet primitive base type is neither BINARY nor FIXED_LEN_BYTE_ARRAY — for instance a DecimalLogicalTypeAnnotation attached to INT32 or INT64 — while creating a Flink Parquet writer.

Common situations: Schemas produced by other systems that store decimals as int-backed Parquet columns; programmatic Parquet schema building with a decimal annotation on the wrong physical type; conversion tools mapping Flink DECIMAL to integer-backed Parquet columns.

Understand the failure class

Background: "is not a compatible type" / "cannot merge" errors: when a value's type doesn't match what the library requires — this error's family across 65 libraries.

Related errors


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