apache/iceberg · error · UncheckedIOException
Failed to deserialize object
Error message
Failed to deserialize object
What it means
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.
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)
Example fix
// before String decoded = new String(Base64.getDecoder().decode(payload)); T obj = SerializationUtil.deserializeFromBytes(decoded.getBytes()); // after byte[] bytes = Base64.getMimeDecoder().decode(payload); T obj = SerializationUtil.deserializeFromBytes(bytes);
Defensive patterns
Strategy: try-catch
Validate before calling
byte[] bytes = Base64.getMimeDecoder().decode(payload);
if (bytes.length < 4 || (bytes[0] & 0xFF) != 0xAC || (bytes[1] & 0xFF) != 0xED) {
throw new IllegalArgumentException("not a Java-serialized payload");
} Type guard
boolean isJavaSerialized(byte[] b) {
return b != null && b.length >= 4 && (b[0] & 0xFF) == 0xAC && (b[1] & 0xFF) == 0xED;
} Try / catch
try {
T obj = SerializationUtil.deserializeFromBytes(bytes);
} catch (UncheckedIOException e) {
log.error("corrupt serialized payload", e);
obj = regeneratePayload();
} Prevention
- 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
When it happens
Trigger: 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).
Common situations: 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.
Understand the failure class
Background: "failed to read file", EACCES, ENOENT and "could not read <path>" errors: when a program can't read a file from disk — this error's family across 49 libraries.
Related errors
- Failed to serialize object
- Cannot convert update requirement to json. Unrecognized type
- Cannot load metadata: metadata file location is null
- Cannot resolve schema for version
- Cannot serialize a Hadoop input file: " + location()
AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12).
Data as JSON: /api/errors/bb3f5e4b4ef24d2d.
Report an issue: GitHub.
Appendix: source
Thrown at core/src/main/java/org/apache/iceberg/util/SerializationUtil.java:82
ObjectOutputStream oos = new ObjectOutputStream(baos)) {
oos.writeObject(obj);
return baos.toByteArray();
} catch (IOException e) {
throw new UncheckedIOException("Failed to serialize object", e);
}
}
@SuppressWarnings({"DangerousJavaDeserialization", "unchecked"})
public static <T> T deserializeFromBytes(byte[] bytes) {
if (bytes == null) {
return null;
}
try (ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
ObjectInputStream ois = new ObjectInputStream(bais)) {
return (T) ois.readObject();
} catch (IOException e) {
throw new UncheckedIOException("Failed to deserialize object", e);
} catch (ClassNotFoundException e) {
throw new RuntimeException("Could not read object ", e);
}
}
public static String serializeToBase64(Object obj) {
byte[] bytes = serializeToBytes(obj);
return new String(Base64.getMimeEncoder().encode(bytes), StandardCharsets.UTF_8);
}
public static <T> T deserializeFromBase64(String base64) {
if (base64 == null) {
return null;
}
byte[] bytes = Base64.getMimeDecoder().decode(base64.getBytes(StandardCharsets.UTF_8));
return deserializeFromBytes(bytes);
}
}View on GitHub (pinned to 86d9c8fc54)