{"record":{"id":"72e95f8589409ad7","repo":"apache/iceberg","slug":"could-not-deserialize-the-writeresult-object","errorCode":null,"errorMessage":"Could not deserialize the WriteResult object","messagePattern":"Could not deserialize the WriteResult object","errorType":"exception","errorClass":"IOException","httpStatus":null,"severity":"error","filePath":"flink/v1.20/flink/src/main/java/org/apache/iceberg/flink/sink/WriteResultSerializer.java","lineNumber":58,"sourceCode":"  public byte[] serialize(WriteResult writeResult) throws IOException {\n    ByteArrayOutputStream out = new ByteArrayOutputStream();\n    DataOutputViewStreamWrapper view = new DataOutputViewStreamWrapper(out);\n    byte[] result = InstantiationUtil.serializeObject(writeResult);\n    view.write(result);\n    return out.toByteArray();\n  }\n\n  @Override\n  public WriteResult deserialize(int version, byte[] serialized) throws IOException {\n    if (version == 1) {\n      DataInputDeserializer view = new DataInputDeserializer(serialized);\n      byte[] resultBuf = new byte[serialized.length];\n      view.read(resultBuf);\n      try {\n        return InstantiationUtil.deserializeObject(\n            resultBuf, IcebergCommittableSerializer.class.getClassLoader());\n      } catch (ClassNotFoundException cnc) {\n        throw new IOException(\"Could not deserialize the WriteResult object\", cnc);\n      }\n    }\n    throw new IOException(\"Unrecognized version or corrupt state: \" + version);\n  }\n}\n","sourceCodeStart":40,"sourceCodeEnd":64,"githubUrl":"https://github.com/apache/iceberg/blob/86d9c8fc543e7c56c9f624eb725f76c9baff9570/flink/v1.20/flink/src/main/java/org/apache/iceberg/flink/sink/WriteResultSerializer.java#L40-L64","documentation":"WriteResultSerializer.deserialize reads an embedded Java-serialized WriteResult buffer and uses InstantiationUtil.deserializeObject; a ClassNotFoundException during that deserialization is rethrown as IOException 'Could not deserialize the WriteResult object'. The bytes are valid, but the class required to decode them is not on the deserializing side's classloader.","triggerScenarios":"Transferring WriteResult committables between Writer/Agregator/Committer operators (or across savepoint restore) when org.apache.iceberg.flink.sink.WriteResult and its nested classes are missing from the user classloader — e.g. user-code classloader lacks the Iceberg jars, or parent-first/child-first classloading isolates the class.","commonSituations":"Running Flink with classloader.check-leaked-classloader or child-first loading where Iceberg classes live in the user jar but the serializer is loaded by a different classloader; savepoint from a different Iceberg version whose WriteResult layout/class moved; shaded/relocated Iceberg packages mismatch.","solutions":["Ensure the iceberg-flink-runtime jar is packaged in the user job jar (not just on the cluster lib path) so the same classloader can resolve WriteResult","Check for classloader conflicts (duplicate or relocated org.apache.iceberg packages) and use user-code-header/unresolved-classloader settings appropriately","Restore savepoints with the same Iceberg version that produced them","Flink 1.19+: try enabling classloader.resolve-order or the compat mode for serializers (execution.checkpointing.unaligned / pipeline.classloader defaults) to keep deserialization on the user classloader"],"exampleFix":"// before\n# iceberg-flink-runtime only in $FLINK_HOME/lib, user jar compiled against different version -> CNFE\n// after\nmvn shade: put iceberg-flink-runtime-1.20-*.jar into the job jar's dependencies\n# or align versions:\n# $FLINK_HOME/lib and job jar both use iceberg-flink-runtime-1.20.0.jar","handlingStrategy":"try-catch","validationCode":"// ensure WriteResult is loadable by the current classloader\nClass.forName(\"org.apache.iceberg.flink.sink.WriteResult\");","typeGuard":"boolean canDeserializeWriteResult() {\n  try {\n    Class.forName(\"org.apache.iceberg.flink.sink.WriteResult\", true,\n        Thread.currentThread().getContextClassLoader());\n    return true;\n  } catch (ClassNotFoundException e) {\n    return false;\n  }\n}","tryCatchPattern":"try {\n  return InstantiationUtil.deserializeObject(buf, loader);\n} catch (IOException e) {\n  if (e.getCause() instanceof ClassNotFoundException) {\n    throw new IllegalStateException(\"Iceberg runtime jar missing from user classloader\", e);\n  }\n  throw e;\n}","preventionTips":["Bundle iceberg-flink-runtime inside the user job jar rather than relying on cluster lib","Verify no relocated/duplicate org.apache.iceberg packages across jars","Restore savepoints with the matching Iceberg version","Test deserialization in a CI job that round-trips WriteResult through the serializer"],"tags":["flink","serialization","classpath","iceberg"],"backgroundTag":"class-not-found","analyzedSha":"86d9c8fc543e7c56c9f624eb725f76c9baff9570","analyzedAt":"2026-09-12T00:46:39.097Z","contentChangedAt":"2026-09-12T00:46:39.097Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}