apache/iceberg · critical · RuntimeException

Unknown serialize version:

Error message

Unknown serialize version: 

What it means

DeltaManifestsSerializer.deserialize throws this when the serialized checkpoint state carries a version byte that is neither VERSION_1 (Iceberg 1.12 and earlier) nor VERSION_2 (1.13+, durable storage based). It exists to fail fast on checkpoint state written by a different Iceberg version rather than silently producing a corrupt DeltaManifests.

Source

Thrown at flink/v2.2/flink/src/main/java/org/apache/iceberg/flink/sink/DeltaManifestsSerializer.java:85

    out.write(deleteManifestBinary);

    CharSequence[] referencedDataFiles = deltaManifests.referencedDataFiles();
    out.writeInt(referencedDataFiles.length);
    for (CharSequence referencedDataFile : referencedDataFiles) {
      out.writeUTF(referencedDataFile.toString());
    }

    return binaryOut.toByteArray();
  }

  @Override
  public DeltaManifests deserialize(int version, byte[] serialized) throws IOException {
    if (version == VERSION_1) {
      return deserializeV1(serialized);
    } else if (version == VERSION_2) {
      return deserializeV2(serialized);
    } else {
      throw new RuntimeException("Unknown serialize version: " + version);
    }
  }

  private DeltaManifests deserializeV1(byte[] serialized) throws IOException {
    return new DeltaManifests(ManifestFiles.decode(serialized), null);
  }

  private DeltaManifests deserializeV2(byte[] serialized) throws IOException {
    ManifestFile dataManifest = null;
    ManifestFile deleteManifest = null;

    ByteArrayInputStream binaryIn = new ByteArrayInputStream(serialized);
    DataInputStream in = new DataInputStream(binaryIn);

    int dataManifestSize = in.readInt();
    if (dataManifestSize > 0) {
      byte[] dataManifestBinary = new byte[dataManifestSize];
      Preconditions.checkState(in.read(dataManifestBinary) == dataManifestSize);

View on GitHub (pinned to 86d9c8fc54)

Solutions

  1. Align the Iceberg runtime version with the one that wrote the checkpoint state (upgrade the deserializing job, don't downgrade).
  2. Take a new savepoint with the target version and resume from that instead of an old savepoint.
  3. If a downgrade is unavoidable, drain the job to a clean finish (stop-with-savepoint --drain) before changing versions so no in-flight committer state remains.

Example fix

// before (resume with older runtime from v2 state)
//   ./bin/flink run -c Job iceberg-flink-runtime-1.12.jar ...
// after
//   ./bin/flink run -c Job iceberg-flink-runtime-1.14.jar ... -s /savepoints/orig-sp
Defensive patterns

Strategy: validation

Validate before calling

// check iceberg version compatibility before resuming from a savepoint
String stateVersion = /* version byte from state meta, if inspectable */;
int VERSION_1 = 1, VERSION_2 = 2;
if (stateVersion != VERSION_1 && stateVersion != VERSION_2) {
  throw new IllegalStateException("Savepoint written by incompatible Iceberg version");
}

Prevention

When it happens

Trigger: Restoring a Flink savepoint/checkpoint whose IcebergFilesCommitter state was written by an Iceberg version whose DeltaManifests VERSION constant is greater than the one on the classpath (downgrade), or state bytes that were manually edited/corrupted in the version byte.

Common situations: Rolling Iceberg back (e.g. 1.14 -> 1.12) while resuming from a savepoint; switching between Iceberg forks/vendors with divergent serialization; a job migrated across clusters with mismatched iceberg-flink-runtime jars.

Related errors


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