apache/iceberg · error · UncheckedIOException
Failed to encode partition
Error message
Failed to encode partition
What it means
encodePartition() serializes a StructLike partition tuple to bytes (length-prefixed, per-field). An IOException from the underlying write path is wrapped in UncheckedIOException. It almost always signals that a partition value cannot be converted to the declared partition field type via Conversions.toByteBuffer.
Solutions
- Ensure the StructLike partition values match partitionType exactly (use PartitionData built from the same Types.StructType)
- Re-derive partitions from the table's current spec rather than reusing cached ones from before a spec change
- Check for type mismatches like Integer vs Long for int/long partition fields and fix the producer
- Catch the UncheckedIOException and log the partition type and values to identify the offending field
Example fix
// before
PartitionData p = new PartitionData(oldSpecPartitionType);
p.set(0, "2024-01-01"); // string for a date field
// after
PartitionData p = new PartitionData(table.spec().partitionType());
p.set(0, LocalDate.parse("2024-01-01")); Defensive patterns
Strategy: validation
Validate before calling
Types.StructType partType = table.spec().partitionType();
for (int i = 0; i < partType.fields().size(); i++) {
Object v = partition.get(i, Object.class);
Preconditions.checkState(v == null || v.getClass() == expectedJavaClass(partType.fields().get(i).type()),
"Partition field %s expects %s but got %s", partType.fields().get(i).name(),
partType.fields().get(i).type(), v == null ? null : v.getClass());
} Try / catch
try {
byte[] encoded = serializer.encodePartition(partition, partitionType);
} catch (UncheckedIOException e) {
LOG.error("Partition encode failed for type {} values {}", partitionType, partition, e);
throw e;
} Prevention
- Always derive partition StructLike values from the table's current spec
- Recompute partition objects after any partition spec evolution
- Write round-trip tests for encodePartition/decodePartition when touching specs
When it happens
Trigger: Passing a partition StructLike whose values don't match partitionType (e.g. mismatched types after spec/schema changes); a null-typed or custom StructLike returning an unexpected object type.
Common situations: Partition spec evolved and the encoder is given old partition objects with a new partition type; manually constructed PartitionData with wrong value types; rows produced by an engine writing partition values in a different representation.
Understand the failure class
Background: "JSON serialization failed", "not JSON serializable", "Failed to serialize": why JSON marshaling errors happen and how to fix them — this error's family across 46 libraries.
Related errors
- Fail to deserialize data statistics
- Fail to serialize aggregated statistics
- Fail to serialize aggregated statistics
- Fail to serialize aggregated statistics
- Fail to serialize data statistics
AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12).
Data as JSON: /api/errors/d21a5d1c318fbb89.
Report an issue: GitHub.
Appendix: source
Thrown at flink/v2.3/flink/src/main/java/org/apache/iceberg/flink/maintenance/operator/StructLikeSerializer.java:88
return new SerializedEqualityValues(baos.toByteArray());
}
public byte[] encodePartition(StructLike partition, Types.StructType partitionType) {
List<Types.NestedField> fields = partitionType.fields();
if (fields.isEmpty()) {
return EMPTY_PARTITION;
}
baos.reset();
try {
for (int i = 0; i < fields.size(); i++) {
writeField(partition, i, fields.get(i).type());
}
dos.flush();
} catch (IOException e) {
throw new UncheckedIOException("Failed to encode partition", e);
}
return baos.toByteArray();
}
public static StructLike decodePartition(byte[] encoded, Types.StructType partitionType) {
PartitionData partition = new PartitionData(partitionType);
List<Types.NestedField> fields = partitionType.fields();
if (fields.isEmpty()) {
return partition;
}
try (DataInputStream dis = new DataInputStream(new ByteArrayInputStream(encoded))) {
for (int i = 0; i < fields.size(); i++) {
boolean isNull = dis.readBoolean();
if (isNull) {
partition.set(i, null);
} else {View on GitHub (pinned to 86d9c8fc54)