apache/iceberg · error · IllegalArgumentException
Unknown read version
Error message
Unknown read version: ${readVersion} What it means
SortKeySerializer.readSnapshot throws IllegalArgumentException when the on-disk serializer snapshot version (readVersion) is neither 1 nor 2. The snapshot encodes which binary layout was used to write SortKey state; a version outside the known set cannot be resolved, typically meaning the state was written by a newer Iceberg/Flink build than the one reading it.
Solutions
- Run the same or newer Iceberg/Flink version that wrote the checkpoint when restoring state
- Downgrade state instead of the runtime: rebuild state from source or a savepoint taken with a compatible writer version
- Check the Iceberg version in the job jar versus the cluster classpath for version skew
Example fix
// before: downgrading iceberg-flink-runtime from 1.20-1.7.x to 1.20-1.5.x while resuming a savepoint // after: keep the writer's Iceberg version (or newer) for the restore ./bin/flink run -c Job job.jar // with iceberg-flink-runtime >= the version that wrote the savepoint
Defensive patterns
Strategy: try-catch
Validate before calling
// before restoring, record the writer version used for the savepoint and compare with the runtime's iceberg-flink version // (no in-process pre-check API; snapshot version is read during restore)
Try / catch
try {
operator.initializeState(state);
} catch (IllegalArgumentException e) {
if (e.getMessage() != null && e.getMessage().contains("Unknown read version")) {
throw new IllegalStateException("Savepoint written by a newer Iceberg version; upgrade the job jar before restoring", e);
}
throw e;
} Prevention
- Never restore a savepoint with an older iceberg-flink-runtime than the one that wrote it
- Pin the Iceberg version across rolling upgrades/downgrades
- Take a fresh savepoint with the target version before rolling back
When it happens
Trigger: Restoring a Flink checkpoint/savepoint (via resolveSchemaCompatibility -> readSnapshot, exercised by roundTrip in tests) whose snapshot bytes contain a version tag greater than the reader's supported versions (1 and 2).
Common situations: Rolling upgrade rollback: job state written with a newer Iceberg Flink sink version is restored by an older runtime; mixing Iceberg versions across cluster restarts; corrupted or hand-edited savepoint metadata.
Understand the failure class
Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.
Related errors
- Failed to initialize serializerCache for reading data with…
- Cannot resolve schema for version
- Failed to deserialize IcebergSourceSplit. Encountered…
- Failed to initialize serializerCache for reading data with…
- Failed to restore committer state. This can happen when…
AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12).
Data as JSON: /api/errors/bf731d00479ba86e.
Report an issue: GitHub.
Appendix: source
Thrown at flink/v1.20/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)