apache/iceberg · error · UnsupportedOperationException

Unsupported shredded value type: ${primitive}

Error message

Unsupported shredded value type: ${primitive}

What it means

The write-side counterpart of the reader check: VariantWriterBuilder.primitive() throws when a shredded Variant typed_value column has a Parquet primitive that has no Variant writer mapping (e.g. FIXED_LEN_BYTE_ARRAY other than UUID, or INT96). The builder cannot produce a ParquetValueWriter for such primitives.

Source

Thrown at parquet/src/main/java/org/apache/iceberg/parquet/VariantWriterBuilder.java:131

              PhysicalType.BOOLEAN_FALSE);
        case INT32:
          return ParquetVariantWriters.primitive(
              ParquetValueWriters.ints(desc), PhysicalType.INT32);
        case INT64:
          return ParquetVariantWriters.primitive(
              ParquetValueWriters.longs(desc), PhysicalType.INT64);
        case FLOAT:
          // use an unboxed writer to skip metrics collection that requires an ID
          return ParquetVariantWriters.primitive(
              ParquetValueWriters.unboxed(desc), PhysicalType.FLOAT);
        case DOUBLE:
          // use an unboxed writer to skip metrics collection that requires an ID
          return ParquetVariantWriters.primitive(
              ParquetValueWriters.unboxed(desc), PhysicalType.DOUBLE);
      }
    }

    throw new UnsupportedOperationException("Unsupported shredded value type: " + primitive);
  }

  @Override
  public ParquetValueWriter<?> value(
      GroupType value, ParquetValueWriter<?> valueWriter, ParquetValueWriter<?> typedWriter) {
    int valueDL = schema.getMaxDefinitionLevel(path(VALUE));
    if (typedWriter != null) {
      int typedValueDL = schema.getMaxDefinitionLevel(path(TYPED_VALUE));
      return ParquetVariantWriters.shredded(valueDL, valueWriter, typedValueDL, typedWriter);
    } else if (value.getType(VALUE).isRepetition(Type.Repetition.OPTIONAL)) {
      return ParquetValueWriters.option(value.getType(VALUE), valueDL, valueWriter);
    } else {
      return valueWriter;
    }
  }

  @Override
  public ParquetValueWriter<?> object(

View on GitHub (pinned to 86d9c8fc54)

Solutions

  1. Change the shredded typed_value type to a spec-allowed primitive (INT64 with timestamp/time logicals instead of INT96; BINARY or uuidType FLBA for bytes).
  2. Disable shredding and write the Variant unshredded so arbitrary types stay inside the variant binary.
  3. Update the pipeline that derives the shredding schema so it filters out unmappable primitives.

Example fix

// before
Types.required(PrimitiveTypeName.FIXED_LEN_BYTE_ARRAY).length(8).named("typed_value")

// after
Types.required(PrimitiveTypeName.FIXED_LEN_BYTE_ARRAY).length(16).as(LogicalTypeAnnotation.uuidType()).named("typed_value")
Defensive patterns

Strategy: validation

Validate before calling

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

Type guard

boolean isWritableShreddedPrimitive(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 {
  buildVariantWriter(schema);
} catch (UnsupportedOperationException e) {
  writeUnshreddedVariant(value);
}

Prevention

When it happens

Trigger: Writing a shredded Variant column whose typed_value primitive is INT96 or a non-UUID FIXED_LEN_BYTE_ARRAY via VariantWriterBuilder.primitive().

Common situations: Custom writer pipelines shredding Variant values into non-conformant Parquet types; porting legacy INT96 timestamp columns into shredded Variant fields; copying a schema from a non-Variant table without adjusting types.

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