{"record":{"id":"a4e8231fdcf71d10","repo":"apache/iceberg","slug":"unknown-read-version-readversion-a4e823","errorCode":null,"errorMessage":"Unknown read version: ${readVersion}","messagePattern":"Unknown read version: (.+?)","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"flink/v2.1/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.1/flink/src/main/java/org/apache/iceberg/flink/sink/shuffle/SortKeySerializer.java#L340-L376","documentation":"SortKeySerializer's snapshot read (SortKeySerializerSnapshot.readSnapshot) deserializes a version marker from the checkpoint stream; only versions 1 and 2 are known. If the marker is anything else, the version byte is corrupt or was written by a newer Iceberg/Flink release, so it throws IllegalArgumentException \"Unknown read version\".","triggerScenarios":"Reading a savepoint/checkpoint whose serialized SortKeySerializerSnapshot contains a version code other than 1 or 2 — typically restoring a job written by a newer Iceberg version into a job running an older version.","commonSituations":"Downgrading the iceberg-flink-runtime version between job restarts; corrupted or hand-edited savepoint metadata; attempting cross-version state compatibility with a build that introduced a new serializer version.","solutions":["Align the iceberg-flink-runtime version of the restoring job with (or be newer than) the version that wrote the savepoint.","If a downgrade is required, start the job from a fresh checkpoint/savepoint taken with the target version instead of restoring old state.","Discard the incompatible state and let the sink re-initialize sort-key statistics (acceptable since they are advisory for data distribution)."],"exampleFix":"// before\n<dependency>org.apache.iceberg:iceberg-flink-runtime-1.19:1.6.0</dependency> // wrote v2 snapshot, then downgraded\n// after: keep runtime version >= writer version across restarts\n<dependency>org.apache.iceberg:iceberg-flink-runtime-1.19:1.9.0</dependency>","handlingStrategy":"fallback","validationCode":"// No pre-call check; verify state provenance before restore\n// Ensure the runtime version that wrote the savepoint <= current runtime version","typeGuard":null,"tryCatchPattern":"try {\n  restoreFrom(savepoint);\n} catch (IllegalArgumentException e) {\n  if (e.getMessage().contains(\"Unknown read version\")) {\n    // start without state or with a savepoint from a compatible version\n  }\n}","preventionTips":["Keep iceberg-flink-runtime at the same or newer version across job restarts","Take fresh savepoints when upgrading/downgrading Iceberg versions","Never hand-edit checkpoint metadata"],"tags":["flink","serialization","version-compatibility","state-restore"],"backgroundTag":"invalid-enum-value","analyzedSha":"86d9c8fc543e7c56c9f624eb725f76c9baff9570","analyzedAt":"2026-09-12T00:46:39.097Z","contentChangedAt":"2026-09-12T00:46:39.097Z","schemaVersion":2},"datasetVersion":"2026-09-14T11:17:12.474Z"}