apache/iceberg · error · UnsupportedOperationException

Unsupported shredded value type: ${primitive}

Error message

Unsupported shredded value type: ${primitive}

What it means

Thrown by VariantReaderBuilder.primitive() when a shredded Variant column's typed_value field has a Parquet primitive type that cannot map to a Variant physical type. FIXED_LEN_BYTE_ARRAY (except UUID) and INT96 are not valid Variant primitives per the Parquet Variant spec, so the reader refuses to build a VariantValueReader.

Source

Thrown at parquet/src/main/java/org/apache/iceberg/parquet/VariantReaderBuilder.java:128

          return ParquetVariantReaders.asVariant(
              PhysicalType.BOOLEAN_TRUE, ParquetValueReaders.unboxed(desc));
        case INT32:
          return ParquetVariantReaders.asVariant(
              PhysicalType.INT32, ParquetValueReaders.unboxed(desc));
        case INT64:
          return ParquetVariantReaders.asVariant(
              PhysicalType.INT64, ParquetValueReaders.unboxed(desc));
        case FLOAT:
          return ParquetVariantReaders.asVariant(
              PhysicalType.FLOAT, ParquetValueReaders.unboxed(desc));
        case DOUBLE:
          return ParquetVariantReaders.asVariant(
              PhysicalType.DOUBLE, ParquetValueReaders.unboxed(desc));
      }
    }

    // note that both FIXED_LEN_BYTE_ARRAY and INT96 are not valid Variant primitives
    throw new UnsupportedOperationException("Unsupported shredded value type: " + primitive);
  }

  @Override
  public VariantValueReader value(
      GroupType group, ParquetValueReader<?> valueReader, ParquetValueReader<?> typedReader) {
    int valueDL =
        valueReader != null ? schema.getMaxDefinitionLevel(path(VALUE)) - 1 : Integer.MAX_VALUE;
    int typedDL =
        typedReader != null
            ? schema.getMaxDefinitionLevel(path(TYPED_VALUE)) - 1
            : Integer.MAX_VALUE;
    return ParquetVariantReaders.shredded(valueDL, valueReader, typedDL, typedReader);
  }

  @Override
  public VariantValueReader object(
      GroupType group,
      ParquetValueReader<?> valueReader,

View on GitHub (pinned to 86d9c8fc54)

Solutions

  1. Rewrite the data so shredded typed_value uses a spec-allowed primitive (e.g. use TIMESTAMP_MICROS/MILLIS logical types instead of INT96; use BINARY or uuidType for byte payloads).
  2. Disable shredding for this column (write the Variant unshredded) and re-encode the table.
  3. If you control the writer, upgrade it to a version that follows the Parquet Variant shredding encoding.
  4. As a workaround, exclude the offending shredded subfield from the projection so the value is read from the unshredded variant metadata/value columns.

Example fix

// before (writer): shredded typed_value as INT96
Types.required(PrimitiveTypeName.INT96).named("typed_value")

// after (writer): conformant timestamp shredding
Types.required(PrimitiveTypeName.INT64).as(LogicalTypeAnnotation.timestampType(true, TimeUnit.MICROS)).named("typed_value")
Defensive patterns

Strategy: validation

Validate before calling

PrimitiveTypeName p = typedValue.getType().asPrimitiveType().getPrimitiveTypeName();
boolean valid = p == BINARY || p == BOOLEAN || p == INT32 || p == INT64 || p == FLOAT || p == DOUBLE
    || (p == FIXED_LEN_BYTE_ARRAY && uuidLogical(typedValue));
Preconditions.checkArgument(valid, "Unsupported shredded primitive: %s", p);

Type guard

boolean isShreddablePrimitive(Type t) {
  if (!t.isPrimitive()) return false;
  PrimitiveTypeName p = t.asPrimitiveType().getPrimitiveTypeName();
  return p != PrimitiveTypeName.INT96
      && (p != PrimitiveTypeName.FIXED_LEN_BYTE_ARRAY || isUuid(t.asPrimitiveType()));
}

Try / catch

try {
  ParquetVariantReaders.open(...);
} catch (UnsupportedOperationException e) {
  // fall back to reading the column unshredded
  readUnshreddedVariant(column);
}

Prevention

When it happens

Trigger: Reading a shredded Variant column whose typed_value primitive is INT96 or a non-UUID FIXED_LEN_BYTE_ARRAY, i.e. VariantReaderBuilder.primitive() encounters an unmapped PrimitiveTypeName.

Common situations: Files written by an older or non-conformant writer that shredded Variant values with unsupported Parquet types; INT96 timestamps (legacy Hive/Impala) mistakenly used as shredded typed_value; custom writers violating the variant shredding spec.

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