apache/iceberg · error · UnsupportedOperationException

Cannot read unsupported column types:

Error message

Cannot read unsupported column types: 

What it means

Thrown by VectorizedCombinedScanIterator when the expected table schema contains column types that the vectorized (Arrow batch) reader cannot decode. The vectorized reader supports a fixed set of Iceberg types (its SUPPORTED_TYPES set); anything outside it aborts the scan instead of silently degrading. This is a fail-fast guard before any batches are produced.

Source

Thrown at arrow/src/main/java/org/apache/iceberg/arrow/vectorized/ArrowReader.java:257

      if (fileTasks.stream().anyMatch(TableScanUtil::hasDeletes)) {
        throw new UnsupportedOperationException(
            "Cannot read files that require applying delete files");
      }

      if (expectedSchema.columns().isEmpty()) {
        throw new UnsupportedOperationException(
            "Cannot read without at least one projected column");
      }

      Set<TypeID> unsupportedTypes =
          Sets.difference(
              expectedSchema.columns().stream()
                  .map(c -> c.type().typeId())
                  .collect(Collectors.toSet()),
              SUPPORTED_TYPES);
      if (!unsupportedTypes.isEmpty()) {
        throw new UnsupportedOperationException(
            "Cannot read unsupported column types: " + unsupportedTypes);
      }

      Map<String, ByteBuffer> keyMetadata = Maps.newHashMap();
      fileTasks.stream()
          .map(FileScanTask::file)
          .forEach(file -> keyMetadata.put(file.location(), file.keyMetadata()));

      Stream<EncryptedInputFile> encrypted =
          keyMetadata.entrySet().stream()
              .map(
                  entry ->
                      EncryptedFiles.encryptedInput(
                          io.newInputFile(entry.getKey()), entry.getValue()));

      // decrypt with the batch call to avoid multiple RPCs to a key server, if possible
      @SuppressWarnings("StreamToIterable")
      Iterable<InputFile> decryptedFiles = encryptionManager.decrypt(encrypted::iterator);

View on GitHub (pinned to 86d9c8fc54)

Solutions

  1. Disable vectorized reads for this scan so the row-based reader is used (e.g. set the reader/vectorization-enabled option to false in Spark: SET spark.sql.iceberg.vectorization.enabled=false).
  2. Check which typeIds are unsupported (the message lists them) and either drop them from the projection or cast them to supported types in the query.
  3. Upgrade Iceberg (and Spark integration) to a version whose SUPPORTED_TYPES includes the column types in the table.
  4. If the type is genuinely new, extend SUPPORTED_TYPES and the corresponding vectorized readers in arrow/src/main/java/org/apache/iceberg/arrow/vectorized/.

Example fix

// before (Spark)
spark.read.format("iceberg").load("db.tbl") // vectorized reader aborts on unsupported type
// after
spark.conf.set("spark.sql.iceberg.vectorization.enabled", "false")
spark.read.format("iceberg").load("db.tbl")
Defensive patterns

Strategy: validation

Validate before calling

import org.apache.iceberg.types.Types;
import org.apache.iceberg.arrow.vectorized.VectorizedArrowReader;
import java.util.Set;
import java.util.stream.Collectors;
Set<Types.TypeID> unsupported = expectedSchema.columns().stream()
    .map(c -> c.type().typeId())
    .filter(id -> !VectorizedArrowReader.SUPPORTED_TYPES.contains(id))
    .collect(Collectors.toSet());
if (!unsupported.isEmpty()) {
  // fall back to non-vectorized read
}

Try / catch

try (CloseableIterator<ColumnarBatch> it = batches) {
  while (it.hasNext()) { consume(it.next()); }
} catch (UnsupportedOperationException e) {
  if (e.getMessage().startsWith("Cannot read unsupported column types")) {
    fallbackToRowBasedReader();
  } else { throw e; }
}

Prevention

When it happens

Trigger: Calling a vectorized/batch read path (e.g. Spark's vectorized reader or ArrowReader.open) on a table whose expected schema resolves to a type not in SUPPORTED_TYPES — e.g. timestamp-with-zone offsets in old versions, unknown/newer Iceberg types, or projected nested types the reader does not handle.

Common situations: Reading a table written by a newer Iceberg version whose types the consuming build's vectorized reader does not know; enabling vectorized reads (spark.sql.iceberg.handle-timestamp-without-timezone / vectorization.enabled style configs) on schemas with exotic types; projecting columns that fall back to unsupported typeIds.

Understand the failure class

Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.

Related errors


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