apache/iceberg · error · java.lang.UnsupportedOperationException

Unsupported base type for decimal: ${primitive.getPrimitiveT

Error message

Unsupported base type for decimal: ${primitive.getPrimitiveTypeName()}

What it means

Iceberg's Spark Parquet reader throws this when a Parquet column carries the DECIMAL logical type but is physically stored with a primitive base type it cannot decode. Only INT32, INT64, BINARY, and FIXED_LEN_BYTE_ARRAY encodings are supported for decimals per the Parquet spec; anything else (e.g. FLOAT, DOUBLE, BOOLEAN) has no defined decimal representation.

Source

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

          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:
          if (expected != null && expected.typeId() == TypeID.LONG) {
            return new IntAsLongReader(desc);
          } else {
            return new UnboxedReader<>(desc);
          }
        case FLOAT:

View on GitHub (pinned to 86d9c8fc54)

Solutions

  1. Rewrite the offending Parquet files with a standard writer so decimals use BINARY, FIXED_LEN_BYTE_ARRAY, INT64, or INT32 physical storage
  2. Verify the Parquet file's schema with parquet-tools/meta and confirm the decimal column's physical type
  3. Check the writer library version that produced the file and upgrade/fix it to emit spec-compliant decimals
  4. Cast/reconvert the data outside Iceberg into a supported physical layout before reading

Example fix

// before: reading a file whose decimal column is stored as FLOAT (invalid)
spark.read.format("iceberg").load("db.table") // throws
// after: rewrite the file with proper decimal physical type
CREATE TABLE fixed STORED AS ... ; INSERT INTO fixed SELECT CAST(dec_col AS DECIMAL(38,10)) FROM bad;
Defensive patterns

Strategy: validation

Validate before calling

// Before reading, verify decimal physical types with parquet-tools
// parquet-tools schema file.parquet | grep -A2 DECIMAL
// Each DECIMAL column must be INT32/INT64/BINARY/FIXED_LEN_BYTE_ARRAY

Prevention

When it happens

Trigger: Reading a Parquet file during a Spark query whose schema contains a decimal column, where the underlying physical column has the DECIMAL logical type annotation but an unexpected physical primitive type (e.g. FLOAT/DOUBLE), typically from a nonstandard writer or a corrupted/hand-edited schema.

Common situations: Files written by third-party or buggy tools that mislabel decimal columns; manually crafted Parquet schemas in tests; version mismatches where a writer emitted decimals with an unsupported encoding.

Related errors


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