baomidou/mybatis-plus · error · IllegalArgumentException
Failed to deserialize object
Error message
Failed to deserialize object
What it means
SerializationUtils.deserialize(bytes) reads an object back via ObjectInputStream; any IOException (corrupt bytes, truncated stream, invalid stream header, stream class version mismatch surfaced as InvalidClassException) is rethrown as IllegalArgumentException('Failed to deserialize object'). The data is unusable — this is not a classpath problem (that produces the ClassNotFoundException branch).
Source
Thrown at mybatis-plus-core/src/main/java/com/baomidou/mybatisplus/core/toolkit/SerializationUtils.java:82
throw new IllegalArgumentException("Failed to serialize object of type: " + object.getClass(), ex);
}
return baos.toByteArray();
}
/**
* Deserialize the byte array into an object.
*
* @param bytes a serialized object
* @return the result of deserializing the bytes
*/
public static Object deserialize(byte[] bytes) {
if (bytes == null) {
return null;
}
try (ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(bytes))) {
return ois.readObject();
} catch (IOException ex) {
throw new IllegalArgumentException("Failed to deserialize object", ex);
} catch (ClassNotFoundException ex) {
throw new IllegalStateException("Failed to deserialize object type", ex);
}
}
}
View on GitHub (pinned to bf67d90747)
Solutions
- Confirm the byte[] actually came from Java serialization — check for the stream header (AC ED 00 05) if reading from storage.
- Use a binary column type (BLOB/BYTEA/VARBINARY(max)), not TEXT/VARCHAR, for serialized payloads.
- Declare an explicit private static final long serialVersionUID on serialized classes so structural changes do not invalidate old data.
- Treat unreadable cached entries as cache misses: delete and regenerate instead of retrying.
Example fix
-- before: serialized bytes stored in TEXT get charset-mangled -> IOException on read ALTER TABLE doc ADD COLUMN payload TEXT; -- after: use a binary column ALTER TABLE doc ADD COLUMN payload BLOB;
Defensive patterns
Strategy: fallback
Validate before calling
if (bytes == null || bytes.length < 4
|| (bytes[0] & 0xFF) != 0xAC || (bytes[1] & 0xFF) != 0xED) {
// not a Java serialization stream; treat as corrupt/cache miss
} Type guard
static boolean looksLikeJavaSerialized(byte[] b) {
return b != null && b.length > 4
&& (b[0] & 0xFF) == 0xAC && (b[1] & 0xFF) == 0xED
&& (b[2] & 0xFF) == 0x00 && (b[3] & 0xFF) == 0x05;
} Try / catch
try {
return SerializationUtils.deserialize(bytes);
} catch (IllegalArgumentException e) {
log.warn("corrupt serialized entry, evicting and recomputing", e);
cache.remove(key);
return recompute(key); // cache-miss style fallback
} Prevention
- Store serialized payloads in binary columns only (BLOB/VARBINARY), never TEXT.
- Evict unreadable cache entries rather than retrying them.
- Pin serialVersionUID on serialized classes.
When it happens
Trigger: Feeding deserialize() bytes that are not a valid Java serialization stream: truncated arrays (DB column too short, e.g. VARCHAR vs BLOB), corrupted cache entries after an unclean shutdown, binary-mangled by charset conversion, or data serialized with an incompatible class layout (serialVersionUID or structural change causing InvalidClassException).
Common situations: Storing serialized blobs in a TEXT/VARCHAR column so the driver mangles bytes; changing entity class structure (adding/removing fields) without maintaining serialVersionUID; cache files surviving a crash; reading bytes that were never produced by serialize() (e.g. JSON or protobuf payload).
Related errors
- Failed to serialize object of type: {}
- Failed to deserialize object type
- Should be specified either value() or name() attribute in th
- Cannot use both value() and name() attribute in the @CacheNa
AI-assisted analysis of baomidou/mybatis-plus@bf67d90747 (2026-08-14).
Data as JSON: /api/errors/4b7d472aaacb07cc.
Report an issue: GitHub.