{"record":{"id":"08373a625d4b9b7e","repo":"apache/iceberg","slug":"unknown-read-version","errorCode":null,"errorMessage":"Unknown read version: ","messagePattern":"Unknown read version: ","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"flink/v2.2/flink/src/main/java/org/apache/iceberg/flink/sink/shuffle/SortKeySerializer.java","lineNumber":358,"sourceCode":"      Preconditions.checkState(sortOrder != null, \"Invalid sort order: null\");\n\n      StringUtils.writeString(SchemaParser.toJson(schema), out);\n      StringUtils.writeString(SortOrderParser.toJson(sortOrder), out);\n    }\n\n    @Override\n    public void readSnapshot(int readVersion, DataInputView in, ClassLoader userCodeClassLoader)\n        throws IOException {\n      switch (readVersion) {\n        case 1:\n          read(in);\n          this.version = 1;\n          break;\n        case 2:\n          read(in);\n          break;\n        default:\n          throw new IllegalArgumentException(\"Unknown read version: \" + readVersion);\n      }\n    }\n\n    @Override\n    public TypeSerializerSchemaCompatibility<SortKey> resolveSchemaCompatibility(\n        TypeSerializerSnapshot<SortKey> oldSerializerSnapshot) {\n      if (!(oldSerializerSnapshot instanceof SortKeySerializerSnapshot)) {\n        return TypeSerializerSchemaCompatibility.incompatible();\n      }\n\n      if (oldSerializerSnapshot.getCurrentVersion() == 1 && this.getCurrentVersion() == 2) {\n        return TypeSerializerSchemaCompatibility.compatibleAfterMigration();\n      }\n\n      // Sort order should be identical\n      SortKeySerializerSnapshot oldSnapshot = (SortKeySerializerSnapshot) oldSerializerSnapshot;\n      if (!sortOrder.sameOrder(oldSnapshot.sortOrder)) {\n        return TypeSerializerSchemaCompatibility.incompatible();","sourceCodeStart":340,"sourceCodeEnd":376,"githubUrl":"https://github.com/apache/iceberg/blob/86d9c8fc543e7c56c9f624eb725f76c9baff9570/flink/v2.2/flink/src/main/java/org/apache/iceberg/flink/sink/shuffle/SortKeySerializer.java#L340-L376","documentation":"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.","triggerScenarios":"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).","commonSituations":"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.","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."],"exampleFix":"// before\nflink run -s chk-100 job.jar   // chk written by Iceberg 1.8.x, runtime is 1.6.x\n// after\n# upgrade flink jobs' iceberg-runtime to the writer version, then restore\nflink run -s chk-100 job.jar","handlingStrategy":"validation","validationCode":"// before restore, verify the savepoint was written by an Iceberg version <= current serializer version\n// e.g. record the writer version in the checkpoint metadata and compare before flink run -s","typeGuard":null,"tryCatchPattern":"try {\n  snapshot.readSnapshot(in);\n} catch (IllegalArgumentException e) {\n  throw new IllegalStateException(\n      \"Checkpoint written by an incompatible Iceberg version; upgrade runtime or start fresh\", e);\n}","preventionTips":["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."],"tags":["flink","serialization","version-compatibility","state-restore"],"backgroundTag":"unexpected-response-shape","analyzedSha":"86d9c8fc543e7c56c9f624eb725f76c9baff9570","analyzedAt":"2026-09-12T00:46:39.097Z","contentChangedAt":"2026-09-12T00:46:39.097Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}