apache/iceberg · error · UncheckedIOException
Failed to serialize PK index key
Error message
Failed to serialize PK index key
What it means
serializeKey() writes the equality-field ids and values of a primary-key (equality) key into Flink keyed state. Any IOException while writing the field bytes is wrapped in UncheckedIOException. In practice this means the underlying StructLike could not be converted for one of the declared key field types (e.g. an unexpected Java type for the field).
Solutions
- Verify the equality key field types match the actual values in the DataStream/schema; fix the schema definition passed to the maintenance source
- Check for schema evolution (added/renamed key fields) between the writing job and the current job and rebuild state
- Log the failing key's field values before this call in a debug run to find which field/value is incompatible
- Update to a newer Iceberg version if a type conversion gap for your field type was fixed
Example fix
// before: key field declared as TimestampType but row supplies LocalDateTime RowType keyType = RowType.of(new TimestampType(), ...); // after: declare the key type matching the supplied Java value RowType keyType = RowType.of(new LocalZonedTimestampType(), ...);
Defensive patterns
Strategy: validation
Validate before calling
for (int i = 0; i < keyType.fields().size(); i++) {
Object v = key.get(i, Object.class);
Preconditions.checkState(v == null || Conversions.tryToByteBuffer(keyType.fields().get(i).type(), v) != null,
"Key field %s value %s not convertible", keyType.fields().get(i).name(), v);
} Try / catch
try {
serializer.serializeKey(key, keyType);
} catch (UncheckedIOException e) {
LOG.error("PK key serialization failed for key {}", key, e);
throw e;
} Prevention
- Keep equality key field types in sync with the RowType/schema used by the job
- Rebuild keyed state after schema/key evolution instead of restoring old state
- Test serialization round-trips of keys in unit tests when changing schemas
When it happens
Trigger: Calling serializeKey with a StructLike whose field values do not match keyType's declared types so Conversions.toByteBuffer throws; a corrupted struct whose get() returns an unconvertible object.
Common situations: Row schema evolved between jobs so the equality key type no longer matches the stored rows; custom StructLike implementations returning unexpected types; upstream produced rows that violate the declared schema.
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/fa8daa18aeba4058.
Report an issue: GitHub.
Appendix: source
Thrown at flink/v2.3/flink/src/main/java/org/apache/iceberg/flink/maintenance/operator/StructLikeSerializer.java:68
private final ByteArrayOutputStream baos = new ByteArrayOutputStream();
private final DataOutputStream dos = new DataOutputStream(baos);
public SerializedEqualityValues serializeKey(StructLike key, Types.StructType keyType) {
baos.reset();
try {
List<Types.NestedField> fields = keyType.fields();
dos.writeInt(fields.size());
for (Types.NestedField field : fields) {
dos.writeInt(field.fieldId());
}
for (int i = 0; i < fields.size(); i++) {
writeField(key, i, fields.get(i).type());
}
dos.flush();
} catch (IOException e) {
throw new UncheckedIOException("Failed to serialize PK index key", e);
}
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();View on GitHub (pinned to 86d9c8fc54)