apache/iceberg · warning · RuntimeException
Fail to deserialize aggregated statistics,change to v1
Error message
Fail to deserialize aggregated statistics,change to v1
What it means
RuntimeException thrown inside StatisticsUtil.deserializeCompletedStatistics when the deserialized CompletedStatistics fails its isValid() check, indicating the current (latest) SortKeySerializer could not correctly parse the checkpoint data. The method then catches it and retries the whole deserialization with sort key serializer version 1, because restoring from a lower version requires the v1 format; if that retry also fails an UncheckedIOException is thrown.
Source
Thrown at flink/v1.20/flink/src/main/java/org/apache/iceberg/flink/sink/shuffle/StatisticsUtil.java:81
static byte[] serializeCompletedStatistics(
CompletedStatistics completedStatistics,
TypeSerializer<CompletedStatistics> statisticsSerializer) {
try {
DataOutputSerializer out = new DataOutputSerializer(1024);
statisticsSerializer.serialize(completedStatistics, out);
return out.getCopyOfBuffer();
} catch (IOException e) {
throw new UncheckedIOException("Fail to serialize aggregated statistics", e);
}
}
static CompletedStatistics deserializeCompletedStatistics(
byte[] bytes, CompletedStatisticsSerializer statisticsSerializer) {
try {
DataInputDeserializer input = new DataInputDeserializer(bytes);
CompletedStatistics completedStatistics = statisticsSerializer.deserialize(input);
if (!completedStatistics.isValid()) {
throw new RuntimeException("Fail to deserialize aggregated statistics,change to v1");
}
return completedStatistics;
} catch (Exception e) {
try {
// If we restore from a lower version, the new version of SortKeySerializer cannot correctly
// parse the checkpointData, so we need to first switch the version to v1. Once the state
// data is successfully parsed, we need to switch the serialization version to the latest
// version to parse the subsequent data passed from the TM.
statisticsSerializer.changeSortKeySerializerVersion(1);
DataInputDeserializer input = new DataInputDeserializer(bytes);
CompletedStatistics deserialize = statisticsSerializer.deserialize(input);
statisticsSerializer.changeSortKeySerializerVersionLatest();
return deserialize;
} catch (IOException ioException) {
throw new UncheckedIOException("Fail to deserialize aggregated statistics", ioException);
}
}View on GitHub (pinned to 86d9c8fc54)
Solutions
- No direct fix needed: the method automatically retries with sort key serializer v1 and switches back to latest afterward
- If the v1 fallback also fails (UncheckedIOException), the checkpoint bytes are incompatible — recreate the job without restoring from the old savepoint
- Ensure the CompletedStatisticsSerializer version handling is active and changeSortKeySerializerVersionLatest is invoked after the v1 parse
- Check the wrapped exception cause to see whether corruption, not versioning, is the root problem
Example fix
// before
CompletedStatistics stats = StatisticsUtil.deserializeCompletedStatistics(bytes, serializer);
// after (library already falls back internally; guard caller side)
try {
CompletedStatistics stats = StatisticsUtil.deserializeCompletedStatistics(bytes, serializer);
} catch (UncheckedIOException e) {
// incompatible old checkpoint; start fresh or re-checkpoint with matching version
throw new IllegalStateException("Aggregated statistics checkpoint incompatible across versions", e);
} Defensive patterns
Strategy: fallback
Validate before calling
// Verify checkpoint was produced with a compatible Iceberg version before restoring boolean compatible = checkpointIcebergVersion.equals(currentIcebergVersion);
Type guard
boolean isRestorable(byte[] bytes, CompletedStatisticsSerializer ser) { try { ser.deserialize(new DataInputDeserializer(bytes)); return true; } catch (Exception e) { return false; } } Try / catch
try { CompletedStatistics s = StatisticsUtil.deserializeCompletedStatistics(bytes, serializer); } catch (UncheckedIOException e) { /* v1 fallback failed; recreate state without restore */ } Prevention
- Upgrade and restore using the same Iceberg version that wrote the checkpoint when possible
- Rely on the built-in v1 fallback rather than pre-parsing bytes manually
- After any cross-version restore, verify subsequent operator traffic parses with the latest serializer
- Keep sort key schema stable across upgrades to avoid invalid parsed statistics
When it happens
Trigger: Restoring a Flink job from a checkpoint/savepoint written by an older Iceberg version while the current job uses the latest SortKeySerializer: the bytes parse but produce an invalid CompletedStatistics, triggering this message and the v1 fallback.
Common situations: Upgrading Iceberg across Flink restores; checkpoints produced with old sort-key serialization mixed with a new version serializer; state migrated between clusters with different Iceberg builds.
Understand the failure class
Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.
Related errors
- Failed to deserialize sort key sketch
- Fail to deserialize data statistics
- Fail to deserialize aggregated statistics,change to v1
- Failed to decode partition
- Failed to deserialize sort key sketch
AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12).
Data as JSON: /api/errors/db9924c95bd15465.
Report an issue: GitHub.