apache/iceberg · error · UnsupportedOperationException

Unsupported logical type: ${primitive.getOriginalType()}

Error message

Unsupported logical type: ${primitive.getOriginalType()}

What it means

SparkParquetReaders switch on the Parquet original (logical) type annotation to pick a reader. A logical type it does not handle (anything outside the known set like UTF8, DATE, DECIMAL, TIMESTAMP, etc.) raises UnsupportedOperationException, meaning Iceberg's Spark reader cannot interpret that Parquet column.

Source

Thrown at spark/v4.2/spark/src/main/java/org/apache/iceberg/spark/data/SparkParquetReaders.java:277

          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 files through Iceberg so logical types conform to the Iceberg spec.
  2. Map unsupported columns to supported types (e.g. cast to string) at write time in the producing system.
  3. Inspect the Parquet schema to identify which column and annotation triggers it.
Defensive patterns

Strategy: validation

Validate before calling

Set<OriginalType> supported = Set.of(UTF8, DATE, DECIMAL, TIMESTAMP_MILLIS, TIMESTAMP_MICROS, INT_8, INT_16, INT_32, INT_64, TIME_MICROS, ENUM, JSON, BSON);
for (ColumnDescriptor cd : schema.getColumns()) {
  if (cd.getPrimitiveType().getOriginalType() != null && !supported.contains(cd.getPrimitiveType().getOriginalType()))
    throw new IllegalStateException("unsupported logical type: " + cd.getPrimitiveType().getOriginalType());
}

Try / catch

try {
  spark.read.format("iceberg").load("tbl");
} catch (UnsupportedOperationException e) {
  if (e.getMessage().startsWith("Unsupported logical type")) {
    // rewrite the files with Iceberg to normalize annotations
  }
}

Prevention

When it happens

Trigger: Reading Parquet files whose columns carry unusual or proprietary logical type annotations (original types) not mapped by the reader, e.g. unusual interval or JSON annotations.

Common situations: Files written by other engines (Impala, Hive, custom writers) with logical types Iceberg doesn't support; schema evolution from external tools.

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