{"record":{"id":"126fcbcf5e43a81d","repo":"apache/iceberg","slug":"unsupported-shredded-value-type-primitive","errorCode":null,"errorMessage":"Unsupported shredded value type: ${primitive}","messagePattern":"Unsupported shredded value type: (.+?)","errorType":"exception","errorClass":"UnsupportedOperationException","httpStatus":null,"severity":"error","filePath":"parquet/src/main/java/org/apache/iceberg/parquet/VariantReaderBuilder.java","lineNumber":128,"sourceCode":"          return ParquetVariantReaders.asVariant(\n              PhysicalType.BOOLEAN_TRUE, ParquetValueReaders.unboxed(desc));\n        case INT32:\n          return ParquetVariantReaders.asVariant(\n              PhysicalType.INT32, ParquetValueReaders.unboxed(desc));\n        case INT64:\n          return ParquetVariantReaders.asVariant(\n              PhysicalType.INT64, ParquetValueReaders.unboxed(desc));\n        case FLOAT:\n          return ParquetVariantReaders.asVariant(\n              PhysicalType.FLOAT, ParquetValueReaders.unboxed(desc));\n        case DOUBLE:\n          return ParquetVariantReaders.asVariant(\n              PhysicalType.DOUBLE, ParquetValueReaders.unboxed(desc));\n      }\n    }\n\n    // note that both FIXED_LEN_BYTE_ARRAY and INT96 are not valid Variant primitives\n    throw new UnsupportedOperationException(\"Unsupported shredded value type: \" + primitive);\n  }\n\n  @Override\n  public VariantValueReader value(\n      GroupType group, ParquetValueReader<?> valueReader, ParquetValueReader<?> typedReader) {\n    int valueDL =\n        valueReader != null ? schema.getMaxDefinitionLevel(path(VALUE)) - 1 : Integer.MAX_VALUE;\n    int typedDL =\n        typedReader != null\n            ? schema.getMaxDefinitionLevel(path(TYPED_VALUE)) - 1\n            : Integer.MAX_VALUE;\n    return ParquetVariantReaders.shredded(valueDL, valueReader, typedDL, typedReader);\n  }\n\n  @Override\n  public VariantValueReader object(\n      GroupType group,\n      ParquetValueReader<?> valueReader,","sourceCodeStart":110,"sourceCodeEnd":146,"githubUrl":"https://github.com/apache/iceberg/blob/86d9c8fc543e7c56c9f624eb725f76c9baff9570/parquet/src/main/java/org/apache/iceberg/parquet/VariantReaderBuilder.java#L110-L146","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["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).","Disable shredding for this column (write the Variant unshredded) and re-encode the table.","If you control the writer, upgrade it to a version that follows the Parquet Variant shredding encoding.","As a workaround, exclude the offending shredded subfield from the projection so the value is read from the unshredded variant metadata/value columns."],"exampleFix":"// before (writer): shredded typed_value as INT96\nTypes.required(PrimitiveTypeName.INT96).named(\"typed_value\")\n\n// after (writer): conformant timestamp shredding\nTypes.required(PrimitiveTypeName.INT64).as(LogicalTypeAnnotation.timestampType(true, TimeUnit.MICROS)).named(\"typed_value\")","handlingStrategy":"validation","validationCode":"PrimitiveTypeName p = typedValue.getType().asPrimitiveType().getPrimitiveTypeName();\nboolean valid = p == BINARY || p == BOOLEAN || p == INT32 || p == INT64 || p == FLOAT || p == DOUBLE\n    || (p == FIXED_LEN_BYTE_ARRAY && uuidLogical(typedValue));\nPreconditions.checkArgument(valid, \"Unsupported shredded primitive: %s\", p);","typeGuard":"boolean isShreddablePrimitive(Type t) {\n  if (!t.isPrimitive()) return false;\n  PrimitiveTypeName p = t.asPrimitiveType().getPrimitiveTypeName();\n  return p != PrimitiveTypeName.INT96\n      && (p != PrimitiveTypeName.FIXED_LEN_BYTE_ARRAY || isUuid(t.asPrimitiveType()));\n}","tryCatchPattern":"try {\n  ParquetVariantReaders.open(...);\n} catch (UnsupportedOperationException e) {\n  // fall back to reading the column unshredded\n  readUnshreddedVariant(column);\n}","preventionTips":["Validate shredding schemas against the Parquet Variant spec before writing files","Never use INT96 for shredded typed_value columns","Only shred FIXED_LEN_BYTE_ARRAY when it carries the UUID logical type","Pin writers to a spec-conformant library version"],"tags":["parquet","variant","shredding","unsupported-type"],"backgroundTag":"unsupported-operation","analyzedSha":"86d9c8fc543e7c56c9f624eb725f76c9baff9570","analyzedAt":"2026-09-12T00:46:39.097Z","contentChangedAt":"2026-09-12T00:46:39.097Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}