apache/iceberg · error · IOException

Unrecognized version or corrupt state: ${version}

Error message

Unrecognized version or corrupt state: ${version}

What it means

DynamicCommittableSerializer.deserialize dispatches on a version byte (VERSION_1/VERSION_2) and throws IOException when the byte matches neither, meaning the serialized committable came from an incompatible serializer version or the bytes are corrupt.

Source

Thrown at flink/v2.1/flink/src/main/java/org/apache/iceberg/flink/sink/dynamic/DynamicCommittableSerializer.java:70

    view.writeInt(numManifests);
    for (int i = 0; i < numManifests; i++) {
      byte[] manifest = committable.manifests()[i];
      view.writeInt(manifest.length);
      view.write(manifest);
    }

    return out.toByteArray();
  }

  @Override
  public DynamicCommittable deserialize(int version, byte[] serialized) throws IOException {
    if (version == VERSION_1) {
      return deserializeV1(serialized);
    } else if (version == VERSION_2) {
      return deserializeV2(serialized);
    }

    throw new IOException("Unrecognized version or corrupt state: " + version);
  }

  private DynamicCommittable deserializeV1(byte[] serialized) throws IOException {
    DataInputDeserializer view = new DataInputDeserializer(serialized);
    WriteTarget key = WriteTarget.deserializeFrom(view);
    String jobId = view.readUTF();
    String operatorId = view.readUTF();
    long checkpointId = view.readLong();
    int manifestLen = view.readInt();
    byte[] manifestBuf = new byte[manifestLen];
    view.read(manifestBuf);
    return new DynamicCommittable(
        new TableKey(key.tableName(), key.branch()),
        new byte[][] {manifestBuf},
        jobId,
        operatorId,
        checkpointId);
  }

View on GitHub (pinned to 86d9c8fc54)

Solutions

  1. Restore with the Iceberg version that wrote the checkpoint, finish the pending commit, then upgrade.
  2. Start fresh (no old savepoint) so committables are produced in the current version.
  3. Validate checkpoint integrity and fall back to an earlier checkpoint if corruption is suspected.
Defensive patterns

Strategy: fallback

Try / catch

try {
  return serializer.deserialize(bytes);
} catch (IOException e) {
  if (e.getMessage().startsWith("Unrecognized version or corrupt state")) {
    // restart without the stale savepoint / use matching Iceberg version
  }
  throw e;
}

Prevention

When it happens

Trigger: Deserializing DynamicCommittables from a checkpoint/savepoint written by an Iceberg version with a different serializer version byte; corrupted committable bytes in operator state.

Common situations: Upgrading iceberg-flink runtime across a restore of in-flight dynamic-sink committables; state corruption in checkpoint storage.

Related errors


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