apache/iceberg · error · java.lang.UnsupportedOperationException

Unsupported type: ${primitive}

Error message

Unsupported type: ${primitive}

What it means

The Iceberg Spark Parquet reader throws this when it encounters a physical Parquet primitive type it does not know how to read. All standard types (BOOLEAN, INT32, INT64, FLOAT, DOUBLE, BINARY, FIXED_LEN_BYTE_ARRAY) plus the legacy INT96 timestamp format are handled; the default branch fires for any remaining/unusual type value, often meaning a corrupted or nonstandard schema.

Source

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

          } else {
            return new UnboxedReader<>(desc);
          }
        case FLOAT:
          if (expected != null && expected.typeId() == TypeID.DOUBLE) {
            return new FloatAsDoubleReader(desc);
          } else {
            return new UnboxedReader<>(desc);
          }
        case BOOLEAN:
        case INT64:
        case DOUBLE:
          return new UnboxedReader<>(desc);
        case INT96:
          // Impala & Spark used to write timestamps as INT96 without a logical type. For backwards
          // compatibility we try to read INT96 as timestamps.
          return ParquetValueReaders.int96Timestamps(desc);
        default:
          throw new UnsupportedOperationException("Unsupported type: " + primitive);
      }
    }

    protected MessageType type() {
      return type;
    }
  }

  private static class BinaryDecimalReader extends PrimitiveReader<Decimal> {
    private final int scale;

    BinaryDecimalReader(ColumnDescriptor desc, int scale) {
      super(desc);
      this.scale = scale;
    }

    @Override
    public Decimal read(Decimal ignored) {

View on GitHub (pinned to 86d9c8fc54)

Solutions

  1. Upgrade Iceberg (and its bundled parquet-mckel) to a version supporting the new primitive type
  2. Inspect the file schema with parquet-tools to identify the offending column and rewrite the file with standard types
  3. Confirm the file is not corrupted by re-downloading or re-exporting the data
  4. If a new type must be read immediately, convert it to a supported type in a pre-processing job

Example fix

// before: reading a file with an unmapped primitive type with an old Iceberg build
spark.read.format("iceberg").load("db.table") // throws
// after: upgrade the Iceberg runtime
// build.gradle: implementation 'org.apache.iceberg:iceberg-spark-runtime-3.5_2.13:<newer-version>'
Defensive patterns

Strategy: try-catch

Validate before calling

// Inspect file schema before the query
// parquet-tools schema file.parquet
// Fail fast on nonstandard primitive types (anything beyond BOOLEAN..FIXED_LEN_BYTE_ARRAY, INT96)

Try / catch

try {
  spark.read.format("iceberg").load("db.table").collect();
} catch (UnsupportedOperationException e) {
  if (e.getMessage().startsWith("Unsupported type:")) {
    // fall back to a non-vectorized/converted read path or repair the files
  } else throw e;
}

Prevention

When it happens

Trigger: A Spark query reads Parquet data whose schema contains a primitive type outside the reader's exhaustive switch — realistically only possible with a corrupted/forward-incompatible file or an exotic future Parquet type added to the parquet-mckel enumeration but not yet mapped by Iceberg.

Common situations: Files produced by a newer Parquet library introducing a new primitive type not yet supported by the Iceberg version in use; corrupted metadata; custom parquet-mckel builds.

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