apache/iceberg · error · RuntimeException
Failed to deserialize the split.
Error message
Failed to deserialize the split.
What it means
IcebergSourceSplit.deserializeV1 uses Java serialization (InstantiationUtil.deserializeObject); if the class of the serialized object cannot be found on the classpath, it wraps ClassNotFoundException into RuntimeException. The split bytes reference classes unavailable at deserialization time.
Source
Thrown at flink/v1.20/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
- Ensure the iceberg-flink runtime jar is on every TaskManager's classpath (or bundled in the user job jar, not both partially).
- Align connector versions between the job that created the checkpoint and the restoring job.
- Check for shade/relocation mismatches (org.apache.iceberg classes relocated differently between builds).
- Inspect the cause ClassNotFoundException for the exact missing class and add the dependency providing it.
Example fix
// before # user jar contains iceberg classes shaded under different package than cluster lib // after # use consistent coordinates: bundle org.apache.iceberg:iceberg-flink-runtime same version in user jar only
Defensive patterns
Strategy: validation
Validate before calling
// Verify the split classes resolve on the restoring cluster before submitting
Class.forName("org.apache.iceberg.flink.source.split.IcebergSourceSplit");
Class.forName("org.apache.iceberg.SerializableTable"); Try / catch
try {
split = IcebergSourceSplitSerializer.INSTANCE.deserialize(version, bytes);
} catch (RuntimeException e) {
if (e.getCause() instanceof ClassNotFoundException) {
throw new IllegalStateException("Iceberg classes missing on TaskManager classpath", e);
}
throw e;
} Prevention
- Bundle the full iceberg-flink-runtime jar in the user job jar
- Keep the same connector version between checkpoint write and restore
- Avoid inconsistent shade relocations of org.apache.iceberg packages
- Check cause ClassNotFoundException to pinpoint missing dependency
When it happens
Trigger: Restoring a checkpoint/savepoint or transferring split bytes where IcebergSourceSplit (or its referenced classes, e.g., the table/SerializableTable) is not on the TaskManager classpath, or was serialized by a different connector version with moved classes.
Common situations: Missing Iceberg jars on TaskManagers; shading conflicts relocating class packages; restoring state across connector versions with relocated classes.
Related errors
- Failed to deserialize the split.
- Could not deserialize the WriteResult object
- Could not deserialize the WriteResult object
- Could not deserialize the WriteResult object
- Failed to deserialize the split.
AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12).
Data as JSON: /api/errors/6b914879831b171c.
Report an issue: GitHub.