apache/iceberg · error · UnsupportedOperationException

Unsupported logical type: " + primitive.getOriginalType()

Error message

Unsupported logical type: " + primitive.getOriginalType()

What it means

The dictionary accessor switch is keyed on the Parquet original (logical) type; if a column's OriginalType is not one of the handled logical types (UTF8, decimal, timestamp variants, int96 timestamp, etc.), the default branch throws this UnsupportedOperationException. It means the logical type has no vectorized dictionary accessor mapping.

Source

Thrown at arrow/src/main/java/org/apache/iceberg/arrow/vectorized/GenericArrowVectorAccessorFactory.java:159

          switch (primitive.getPrimitiveTypeName()) {
            case BINARY:
            case FIXED_LEN_BYTE_ARRAY:
              return new DictionaryDecimalBinaryAccessor<>(
                  (IntVector) vector, dictionary, decimalFactorySupplier.get());
            case INT64:
              return new DictionaryDecimalLongAccessor<>(
                  (IntVector) vector, dictionary, decimalFactorySupplier.get());
            case INT32:
              return new DictionaryDecimalIntAccessor<>(
                  (IntVector) vector, dictionary, decimalFactorySupplier.get());
            default:
              throw new UnsupportedOperationException(
                  "Unsupported base type for decimal: " + primitive.getPrimitiveTypeName());
          }
        default:
          throw new UnsupportedOperationException(
              "Unsupported logical type: " + primitive.getOriginalType());
      }
    } else {
      switch (primitive.getPrimitiveTypeName()) {
        case FIXED_LEN_BYTE_ARRAY:
        case BINARY:
          return new DictionaryBinaryAccessor<>(
              (IntVector) vector, dictionary, stringFactorySupplier.get());
        case FLOAT:
          return new DictionaryFloatAccessor<>((IntVector) vector, dictionary);
        case INT64:
          return new DictionaryLongAccessor<>((IntVector) vector, dictionary);
        case INT96:
          // Impala & Spark used to write timestamps as INT96 by default. For backwards
          // compatibility we try to read INT96 as timestamps. But INT96 is not recommended
          // and deprecated (see https://issues.apache.org/jira/browse/PARQUET-323)
          return new DictionaryTimestampInt96Accessor<>((IntVector) vector, dictionary);
        case DOUBLE:
          return new DictionaryDoubleAccessor<>((IntVector) vector, dictionary);
        default:

View on GitHub (pinned to 86d9c8fc54)

Solutions

  1. Upgrade Iceberg/parquet-mr to a version mapping the column's logical type
  2. Drop the unsupported logical annotation by rewriting the column as its base physical type
  3. Read these columns through the non-vectorized path
Defensive patterns

Strategy: fallback

Validate before calling

if (!SUPPORTED_LOGICAL_TYPES.contains(primitive.getOriginalType())) { useRowReader(column); }

Try / catch

try { accessor = factory.getVectorAccessor(holder); } catch (UnsupportedOperationException e) { if (e.getMessage().startsWith("Unsupported logical type")) { accessor = rowAccessor(holder); } else throw e; }

Prevention

When it happens

Trigger: Reading a dictionary-encoded column whose Parquet logical type is unmapped (e.g. newer logical types like JSON, BSON, UUID, or unknown future types) through the vectorized read path.

Common situations: Files written with newer Parquet logical annotations than this Iceberg version supports; forward-compatibility gaps after Parquet spec additions without upgrading Iceberg.

Related errors


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