apache/iceberg · error · UnsupportedOperationException

Unsupported base type for decimal: " + primitive.getPrimitiv

Error message

Unsupported base type for decimal: " + primitive.getPrimitiveTypeName()

What it means

This is the same 'Unsupported base type for decimal' error thrown from the non-dictionary branch of getVectorAccessor (line 157 vs 256 for the dictionary branch). A plain (non-dictionary-encoded) decimal column's Parquet base type is not one of the supported physical types, so accessor construction fails.

Source

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

          return new DictionaryLongAccessor<>((IntVector) vector, dictionary);
        case DECIMAL:
          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:

View on GitHub (pinned to 86d9c8fc54)

Solutions

  1. Validate the Parquet schema's physical type for decimal columns before vectorized reads
  2. Rewrite the files with standard writers (decimal over FIXED_LEN_BYTE_ARRAY/INT64/INT32)
  3. Use the generic Parquet row reader for these files instead of the Arrow path
Defensive patterns

Strategy: fallback

Validate before calling

if (decimalPhysicalTypes.stream().noneMatch(t -> t == primitive.getPrimitiveTypeName())) { skipVectorized(column); }

Try / catch

try { accessor = factory.getVectorAccessor(holder); } catch (UnsupportedOperationException e) { if (e.getMessage().startsWith("Unsupported base type for decimal")) { accessor = null; } else throw e; }

Prevention

When it happens

Trigger: getVectorAccessor resolving a plain decimal column whose PrimitiveTypeName is outside FIXED_LEN_BYTE_ARRAY/BINARY, INT64, INT32; passing a malformed or foreign Parquet schema to the Arrow accessor factory.

Common situations: External Parquet files (non-Iceberg writers) registered directly; corrupted or hand-edited Parquet metadata claiming decimal logical type over an unsupported physical type.

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