{"record":{"id":"bb3f5e4b4ef24d2d","repo":"apache/iceberg","slug":"failed-to-deserialize-object","errorCode":null,"errorMessage":"Failed to deserialize object","messagePattern":"Failed to deserialize object","errorType":"exception","errorClass":"UncheckedIOException","httpStatus":null,"severity":"error","filePath":"core/src/main/java/org/apache/iceberg/util/SerializationUtil.java","lineNumber":82,"sourceCode":"        ObjectOutputStream oos = new ObjectOutputStream(baos)) {\n      oos.writeObject(obj);\n      return baos.toByteArray();\n    } catch (IOException e) {\n      throw new UncheckedIOException(\"Failed to serialize object\", e);\n    }\n  }\n\n  @SuppressWarnings({\"DangerousJavaDeserialization\", \"unchecked\"})\n  public static <T> T deserializeFromBytes(byte[] bytes) {\n    if (bytes == null) {\n      return null;\n    }\n\n    try (ByteArrayInputStream bais = new ByteArrayInputStream(bytes);\n        ObjectInputStream ois = new ObjectInputStream(bais)) {\n      return (T) ois.readObject();\n    } catch (IOException e) {\n      throw new UncheckedIOException(\"Failed to deserialize object\", e);\n    } catch (ClassNotFoundException e) {\n      throw new RuntimeException(\"Could not read object \", e);\n    }\n  }\n\n  public static String serializeToBase64(Object obj) {\n    byte[] bytes = serializeToBytes(obj);\n    return new String(Base64.getMimeEncoder().encode(bytes), StandardCharsets.UTF_8);\n  }\n\n  public static <T> T deserializeFromBase64(String base64) {\n    if (base64 == null) {\n      return null;\n    }\n    byte[] bytes = Base64.getMimeDecoder().decode(base64.getBytes(StandardCharsets.UTF_8));\n    return deserializeFromBytes(bytes);\n  }\n}","sourceCodeStart":64,"sourceCodeEnd":100,"githubUrl":"https://github.com/apache/iceberg/blob/86d9c8fc543e7c56c9f624eb725f76c9baff9570/core/src/main/java/org/apache/iceberg/util/SerializationUtil.java#L64-L100","documentation":"SerializationUtil.deserializeFromBytes wraps Java's native ObjectInputStream deserialization. An IOException during readObject (corrupt/truncated bytes, stream-header mismatch, or a readObject method throwing internally) is rethrown as an UncheckedIOException with this message. It means the byte array is not a valid Java-serialized stream for the expected object.","triggerScenarios":"Calling deserializeFromBytes (directly or via deserializeFromBase64) with bytes that were not produced by serializeToBytes, Base64 strings decoded incorrectly (wrong decoder, e.g. plain Base64 vs MIME), truncated/corrupted payloads stored in configs or event payloads, or serialized data whose embedded objects fail during readObject (e.g. serialVersionUID mismatch is often surfaced through this path).","commonSituations":"Passing a plain-text or JSON string where a Java-serialized payload is expected; hand-editing or re-encoding Base64 payloads with whitespace/newlines stripped inconsistently with the MIME encoder; upgrading library versions so a stored serialized object no longer round-trips.","solutions":["Verify the payload was produced by SerializationUtil.serializeToBytes/serializeToBase64 in the first place","Decode Base64 with Base64.getMimeDecoder() (the matching decoder for getMimeEncoder) and check the bytes start with the Java stream magic 0xAC 0xED","Regenerate the payload from the source object instead of reusing stored bytes","Inspect the chained IOException cause for the real failure (e.g. invalid stream header, class resolution)"],"exampleFix":"// before\nString decoded = new String(Base64.getDecoder().decode(payload));\nT obj = SerializationUtil.deserializeFromBytes(decoded.getBytes());\n// after\nbyte[] bytes = Base64.getMimeDecoder().decode(payload);\nT obj = SerializationUtil.deserializeFromBytes(bytes);","handlingStrategy":"try-catch","validationCode":"byte[] bytes = Base64.getMimeDecoder().decode(payload);\nif (bytes.length < 4 || (bytes[0] & 0xFF) != 0xAC || (bytes[1] & 0xFF) != 0xED) {\n  throw new IllegalArgumentException(\"not a Java-serialized payload\");\n}","typeGuard":"boolean isJavaSerialized(byte[] b) {\n  return b != null && b.length >= 4 && (b[0] & 0xFF) == 0xAC && (b[1] & 0xFF) == 0xED;\n}","tryCatchPattern":"try {\n  T obj = SerializationUtil.deserializeFromBytes(bytes);\n} catch (UncheckedIOException e) {\n  log.error(\"corrupt serialized payload\", e);\n  obj = regeneratePayload();\n}","preventionTips":["Only round-trip through serializeToBytes/serializeToBase64 pairs","Use the matching MIME Base64 encoder/decoder","Prefer stable formats (JSON/Avro) for cross-process payloads","Never hand-edit or truncate serialized payloads"],"tags":["serialization","java-io"],"backgroundTag":"file-read-failed","analyzedSha":"86d9c8fc543e7c56c9f624eb725f76c9baff9570","analyzedAt":"2026-09-12T00:46:39.097Z","contentChangedAt":"2026-09-12T00:46:39.097Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}