apache/iceberg · error · UnsupportedOperationException

Unsupported logical type:

Error message

Unsupported logical type: 

What it means

SparkParquetReaders.primitive() handles Parquet logical (original) types. When a column carries a logical type annotation that this reader does not implement (the default branch after handling DECIMAL, BSON, etc.), it throws UnsupportedOperationException with the original type name. Reading cannot proceed for that column.

Source

Thrown at spark/v4.0/spark/src/main/java/org/apache/iceberg/spark/data/SparkParquetReaders.java:263

          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. Identify the logical type via parquet-tools schema output and compare against the handled types in SparkParquetReaders
  2. Rewrite the affected data files with Iceberg/Spark so columns use supported logical types (or plain physical types)
  3. Update the Iceberg table schema so the column maps to a supported type (e.g. string/bytes instead of the unsupported annotation)
  4. Upgrade Iceberg if the logical type is supported in newer releases
Defensive patterns

Strategy: validation

Validate before calling

// Before registering external files, check for unsupported logical annotations
parquetSchema.getColumns().forEach(col -> {
  OriginalType ot = col.getPrimitive().getOriginalType();
  if (ot != null && !SUPPORTED_LOGICAL_TYPES.contains(ot)) {
    throw new IllegalStateException("Unsupported logical type in file: " + ot);
  }
});

Try / catch

try {
  spark.read().format("iceberg").load("db.tbl");
} catch (UnsupportedOperationException e) {
  if (e.getMessage().startsWith("Unsupported logical type")) {
    // rewrite the files with supported logical types, then retry the read
  } else {
    throw e;
  }
}

Prevention

When it happens

Trigger: Spark read of an Iceberg Parquet table where a column's Parquet OriginalType is one not covered by the switch (e.g. exotic/legacy logical annotations such as some converted types this branch does not map).

Common situations: Files produced by older or non-Iceberg Parquet writers carrying legacy ConvertedType annotations; schema drift after external tools rewrote files; reading data written by a newer Parquet logical-type spec than this reader supports.

Related errors


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