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

  1. Upgrade the cluster/submit-side Iceberg flink runtime to the version that wrote the state (version byte must be <= 2 for this build).
  2. If downgrading is intentional, restart without restoring this operator state (--allowNonRestoredState) or take a fresh savepoint with the older version.
  3. 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

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


AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12). Data as JSON: /api/errors/08373a625d4b9b7e. Report an issue: GitHub.