apache/iceberg · error · IllegalArgumentException
Unknown read version:
Error message
Unknown read version:
What it means
SortKeySerializer's TypeSerializerSnapshot (readSnapshot) reads the version byte written alongside the serializer and only understands versions 1 (read with the old format) and 2 (read(in)). Any other version byte makes the snapshot unparseable, so it throws IllegalArgumentException "Unknown read version". This protects against restoring state written by an incompatible Iceberg/Flink version.
Source
Thrown at flink/v2.2/flink/src/main/java/org/apache/iceberg/flink/sink/shuffle/SortKeySerializer.java:358
Preconditions.checkState(sortOrder != null, "Invalid sort order: null");
StringUtils.writeString(SchemaParser.toJson(schema), out);
StringUtils.writeString(SortOrderParser.toJson(sortOrder), out);
}
@Override
public void readSnapshot(int readVersion, DataInputView in, ClassLoader userCodeClassLoader)
throws IOException {
switch (readVersion) {
case 1:
read(in);
this.version = 1;
break;
case 2:
read(in);
break;
default:
throw new IllegalArgumentException("Unknown read version: " + readVersion);
}
}
@Override
public TypeSerializerSchemaCompatibility<SortKey> resolveSchemaCompatibility(
TypeSerializerSnapshot<SortKey> oldSerializerSnapshot) {
if (!(oldSerializerSnapshot instanceof SortKeySerializerSnapshot)) {
return TypeSerializerSchemaCompatibility.incompatible();
}
if (oldSerializerSnapshot.getCurrentVersion() == 1 && this.getCurrentVersion() == 2) {
return TypeSerializerSchemaCompatibility.compatibleAfterMigration();
}
// Sort order should be identical
SortKeySerializerSnapshot oldSnapshot = (SortKeySerializerSnapshot) oldSerializerSnapshot;
if (!sortOrder.sameOrder(oldSnapshot.sortOrder)) {
return TypeSerializerSchemaCompatibility.incompatible();View on GitHub (pinned to 86d9c8fc54)
Solutions
- Upgrade the cluster/submit-side Iceberg flink runtime to the version that wrote the state (version byte must be <= 2 for this build).
- If downgrading is intentional, restart without restoring this operator state (--allowNonRestoredState) or take a fresh savepoint with the older version.
- Validate checkpoint integrity if corruption is suspected; restore from an earlier valid checkpoint.
Example fix
// before flink run -s chk-100 job.jar // chk written by Iceberg 1.8.x, runtime is 1.6.x // after # upgrade flink jobs' iceberg-runtime to the writer version, then restore flink run -s chk-100 job.jar
Defensive patterns
Strategy: validation
Validate before calling
// before restore, verify the savepoint was written by an Iceberg version <= current serializer version // e.g. record the writer version in the checkpoint metadata and compare before flink run -s
Try / catch
try {
snapshot.readSnapshot(in);
} catch (IllegalArgumentException e) {
throw new IllegalStateException(
"Checkpoint written by an incompatible Iceberg version; upgrade runtime or start fresh", e);
} Prevention
- Match Iceberg versions between the job that wrote the savepoint and the one restoring it.
- Take a fresh savepoint with the target version before rolling upgrades/downgrades.
- Never hand-edit or truncate checkpoint files.
When it happens
Trigger: Restoring a Flink savepoint/checkpoint whose serialized SortKeySerializerSnapshot was written by a newer Iceberg version that bumped the serializer version beyond 2 (or by corrupted state where the version byte is garbage).
Common situations: Rolling upgrade: new operators read checkpoints written by newer code; restoring state on a cluster with an older Iceberg flink jar than the one that wrote the state; truncated or corrupted checkpoint files.
Related errors
- Unknown read version: ${readVersion}
- Failed to deserialize IcebergSourceSplit. Encountered unsupp
- Unknown serialize version:
- Unrecognized version or corrupt state: ${version}
- Failed to deserialize IcebergSourceSplit. Encountered unsupp
AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12).
Data as JSON: /api/errors/08373a625d4b9b7e.
Report an issue: GitHub.