apache/iceberg · error · IllegalArgumentException
Unsupported data statistics type: ${statisticsType}
Error message
Unsupported data statistics type: ${statisticsType} What it means
DataStatisticsSerializer.copy supports copying statistics objects of known StatisticsType values; when the type is neither Map nor Sketch it cannot pick a copy strategy and throws. The type comes from the DataStatistics object being copied, so an unsupported value implies an unknown/newer statistics implementation.
Source
Thrown at flink/v2.1/flink/src/main/java/org/apache/iceberg/flink/sink/shuffle/DataStatisticsSerializer.java:91
public DataStatistics copy(DataStatistics obj) {
StatisticsType statisticsType = obj.type();
if (statisticsType == StatisticsType.Map) {
MapDataStatistics from = (MapDataStatistics) obj;
Map<SortKey, Long> fromStats = (Map<SortKey, Long>) from.result();
Map<SortKey, Long> toStats = Maps.newHashMap(fromStats);
return new MapDataStatistics(toStats);
} else if (statisticsType == StatisticsType.Sketch) {
// because ReservoirItemsSketch doesn't expose enough public methods for cloning,
// this implementation adopted the less efficient serialization and deserialization.
SketchDataStatistics from = (SketchDataStatistics) obj;
ReservoirItemsSketch<SortKey> fromStats = (ReservoirItemsSketch<SortKey>) from.result();
byte[] bytes = fromStats.toByteArray(sketchSerializer);
Memory memory = Memory.wrap(bytes);
ReservoirItemsSketch<SortKey> toStats =
ReservoirItemsSketch.heapify(memory, sketchSerializer);
return new SketchDataStatistics(toStats);
} else {
throw new IllegalArgumentException("Unsupported data statistics type: " + statisticsType);
}
}
@Override
public DataStatistics copy(DataStatistics from, DataStatistics reuse) {
// not much benefit to reuse
return copy(from);
}
@Override
public int getLength() {
return -1;
}
@SuppressWarnings("unchecked")
@Override
public void serialize(DataStatistics obj, DataOutputView target) throws IOException {
StatisticsType statisticsType = obj.type();View on GitHub (pinned to 86d9c8fc54)
Solutions
- Align Iceberg connector versions on all nodes of the Flink job.
- Only feed DataStatistics instances produced by this serializer/connector (Map or Sketch types).
- Upgrade the connector so newer statistics types are recognized.
Defensive patterns
Strategy: type-guard
Validate before calling
StatisticsType t = from.type();
if (t != StatisticsType.Map && t != StatisticsType.Sketch) {
throw new IllegalArgumentException("Cannot copy statistics of type " + t);
} Type guard
boolean isCopyable(DataStatistics s) {
return s.type() == StatisticsType.Map || s.type() == StatisticsType.Sketch;
} Try / catch
try {
DataStatistics copy = serializer.copy(from, null);
} catch (IllegalArgumentException e) {
if (e.getMessage().startsWith("Unsupported data statistics type")) {
// fall back to map-based statistics or re-create from raw data
} else throw e;
} Prevention
- Only exchange DataStatistics produced by the same connector version.
- Keep StatisticsType handling in sync when extending the library.
- Avoid mixed connector jars on the cluster classpath.
When it happens
Trigger: Calling copy() on a DataStatistics whose type() returns a StatisticsType other than Map or Sketch, e.g. a statistics object created by a newer connector version.
Common situations: Mixed connector versions across the Flink cluster during the data-statistics shuffle handshake, or custom DataStatistics implementations passed into the serializer.
Related errors
- Fail to serialize data statistics
- Fail to serialize aggregated statistics
- The Avro schema is not a nullable type: ${schema}
- Fail to serialize at field: %s.
- Unrecognized version or corrupt state: <version>
AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12).
Data as JSON: /api/errors/11c9b2117bc56508.
Report an issue: GitHub.