apache/iceberg · error · RuntimeException

Failed to deserialize the split.

Error message

Failed to deserialize the split.

What it means

deserializeV1 deserializes a version-1 serialized IcebergSourceSplit using Flink's InstantiationUtil Java serialization. If the bytes reference a class not present on the classpath, ClassNotFoundException is wrapped in this RuntimeException. It indicates the split state bytes cannot be reconstructed in the current runtime.

Source

Thrown at flink/v2.3/flink/src/main/java/org/apache/iceberg/flink/source/split/IcebergSourceSplit.java:131

                        .add("length", fileScanTask.length())
                        .toString())
            .collect(Collectors.toList()));
  }

  byte[] serializeV1() throws IOException {
    if (serializedBytesCache == null) {
      serializedBytesCache = InstantiationUtil.serializeObject(this);
    }

    return serializedBytesCache;
  }

  static IcebergSourceSplit deserializeV1(byte[] serialized) throws IOException {
    try {
      return InstantiationUtil.deserializeObject(
          serialized, IcebergSourceSplit.class.getClassLoader());
    } catch (ClassNotFoundException e) {
      throw new RuntimeException("Failed to deserialize the split.", e);
    }
  }

  byte[] serializeV2() throws IOException {
    return serialize(2);
  }

  byte[] serializeV3() throws IOException {
    return serialize(3);
  }

  private byte[] serialize(int version) throws IOException {
    if (serializedBytesCache == null) {
      DataOutputSerializer out = SERIALIZER_CACHE.get();
      Collection<FileScanTask> fileScanTasks = task.tasks();
      Preconditions.checkArgument(
          fileOffset >= 0 && fileOffset < fileScanTasks.size(),
          "Invalid file offset: %s. Should be within the range of [0, %s)",

View on GitHub (pinned to 86d9c8fc54)

Solutions

  1. Use the same Iceberg version (or a compatible one) that wrote the savepoint when restoring.
  2. If upgrade is required, let the old job finish or drain rather than restoring old split state into a new Iceberg version.
  3. Verify the shaded jar contains all org.apache.iceberg.flink split classes (no class relocation mismatch).
  4. Check Flink classloader settings (classloader.check-leaked-classloader, parent-first/child-first) if ClassNotFoundException appears only at runtime.
Defensive patterns

Strategy: try-catch

Try / catch

try { split = IcebergSourceSplit.deserializeV1(bytes); } catch (RuntimeException e) { if (e.getCause() instanceof ClassNotFoundException) { throw new IllegalStateException('Savepoint written with a different Iceberg version; restore with matching version', e); } throw e; }

Prevention

When it happens

Trigger: Restoring a Flink savepoint/checkpoint whose operator state contains serialized splits referencing classes (e.g. old split or table classes) not found by the current classloader - typically after upgrading Iceberg or relocating/renaming classes.

Common situations: Upgrading the Iceberg version between a job stop-with-savepoint and resume; fat-jar shading issues where serializer classes are excluded; classloader isolation in Flink per-job/user-code classloaders.

Related errors


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