apache/iceberg · error · UnsupportedOperationException

Unsupported base type for decimal:

Error message

Unsupported base type for decimal: 

What it means

SparkParquetReaders.primitive builds decimal readers from the Parquet physical base type: only BINARY (fixed_len_byte_array path), INT64, and INT32 are supported for DECIMAL logical types. Any other base type annotated as decimal hits the default branch. This UnsupportedOperationException reports a Parquet decimal stored on an unsupported physical type.

Source

Thrown at spark/v3.5/spark/src/main/java/org/apache/iceberg/spark/data/SparkParquetReaders.java:240

          case DATE:
          case INT_64:
            return new UnboxedReader<>(desc);
          case TIMESTAMP_MICROS:
          case TIMESTAMP_MILLIS:
            return ParquetValueReaders.timestamps(desc);
          case DECIMAL:
            DecimalLogicalTypeAnnotation decimal =
                (DecimalLogicalTypeAnnotation) primitive.getLogicalTypeAnnotation();
            switch (primitive.getPrimitiveTypeName()) {
              case BINARY:
              case FIXED_LEN_BYTE_ARRAY:
                return new BinaryDecimalReader(desc, decimal.getScale());
              case INT64:
                return new LongDecimalReader(desc, decimal.getPrecision(), decimal.getScale());
              case INT32:
                return new IntegerDecimalReader(desc, decimal.getPrecision(), decimal.getScale());
              default:
                throw new UnsupportedOperationException(
                    "Unsupported base type for decimal: " + primitive.getPrimitiveTypeName());
            }
          case BSON:
            return new ParquetValueReaders.ByteArrayReader(desc);
          default:
            throw new UnsupportedOperationException(
                "Unsupported logical type: " + primitive.getOriginalType());
        }
      }

      switch (primitive.getPrimitiveTypeName()) {
        case FIXED_LEN_BYTE_ARRAY:
        case BINARY:
          if (expected != null && expected.typeId() == TypeID.UUID) {
            return new UUIDReader(desc);
          }
          return new ParquetValueReaders.ByteArrayReader(desc);
        case INT32:

View on GitHub (pinned to 86d9c8fc54)

Solutions

  1. Rewrite the Parquet data with a standard writer storing decimals on BINARY, INT32, or INT64 base types.
  2. Verify the file's writer and re-export the data with proper decimal encoding.
  3. Read the file with a tolerant reader/tool to confirm its actual schema, then fix upstream.
  4. Upgrade Iceberg if the file uses a legal Parquet decimal encoding the reader should support.
Defensive patterns

Strategy: validation

Validate before calling

org.apache.parquet.schema.PrimitiveType pt = desc.asPrimitiveType();
if (pt.getPrimitiveTypeName().getJavaType() != org.apache.parquet.schema.PrimitiveType.PrimitiveTypeName.BINARY
    && pt.getPrimitiveTypeName() != org.apache.parquet.schema.PrimitiveTypeName.INT64
    && pt.getPrimitiveTypeName() != org.apache.parquet.schema.PrimitiveTypeName.INT32) {
  throw new IllegalStateException("Decimal must use BINARY/INT32/INT64 base type, got " + pt.getPrimitiveTypeName());
}

Prevention

When it happens

Trigger: Reading a Parquet file whose DECIMAL logical type is annotated on a physical type other than BINARY/FIXED_LEN_BYTE_ARRAY, INT64, or INT32 (e.g. FLOAT/DOUBLE or FIXED_LEN_BYTE_ARRAY handled elsewhere producing this in the annotated path).

Common situations: Files written by non-standard Parquet writers that store decimals on float/double or unusual base types; corrupted or hand-crafted Parquet schemas.

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/c4f02254da4b4908. Report an issue: GitHub.