google/gson · error · InvalidObjectException
Deserialization is unsupported
Error message
Deserialization is unsupported
What it means
Thrown by LinkedTreeMap.readObject(ObjectInputStream) as InvalidObjectException. LinkedTreeMap's writeReplace() converts it to a LinkedHashMap on serialization so the receiver does not need Gson; direct Java deserialization back into a LinkedTreeMap is therefore intentionally blocked. The class comment also notes Java serialization defeats Gson's DoS defences, so it is discouraged.
Source
Thrown at gson/src/main/java/com/google/gson/internal/LinkedTreeMap.java:675
@Override
public void clear() {
LinkedTreeMap.this.clear();
}
}
/**
* If somebody is unlucky enough to have to serialize one of these, serialize it as a
* LinkedHashMap so that they won't need Gson on the other side to deserialize it. Using
* serialization defeats our DoS defence, so most apps shouldn't use it.
*/
private Object writeReplace() throws ObjectStreamException {
return new LinkedHashMap<>(this);
}
private void readObject(ObjectInputStream in) throws IOException {
// Don't permit directly deserializing this class; writeReplace() should have written a
// replacement
throw new InvalidObjectException("Deserialization is unsupported");
}
}
View on GitHub (pinned to 8b8628c656)
Solutions
- Do not Java-serialize LinkedTreeMap; persist via Gson JSON (toJson/fromJson) instead.
- If you must use Java serialization, copy entries into a LinkedHashMap before serializing and read them back as a LinkedHashMap.
- Upgrade Gson and avoid storing raw internal map instances in serialized fields.
Example fix
// before ObjectOutputStream out = ... out.writeObject(linkedTreeMap); // internal type ObjectInputStream in = ... Map<?,?> m = (Map<?,?>) in.readObject(); // InvalidObjectException // after: serialize as a standard map or JSON out.writeObject(new LinkedHashMap<>(linkedTreeMap));
Defensive patterns
Strategy: try-catch
Validate before calling
// Convert to a portable map before Java serialization
static Map<?, ?> portable(Map<?, ?> m) {
return new LinkedHashMap<>(m);
}
// usage: out.writeObject(portable(linkedTreeMap)); Type guard
static boolean isJavaSerializableMap(Object o) {
return o instanceof LinkedHashMap || o instanceof HashMap;
} Try / catch
try {
Object o = in.readObject();
} catch (InvalidObjectException e) {
if (e.getMessage().contains("Deserialization is unsupported")) {
// switch to JSON-based persistence
throw new IllegalStateException("Persist via Gson JSON, not Java serialization", e);
} else throw e;
} Prevention
- Do not Java-serialize LinkedTreeMap; use JSON transport.
- Copy entries into LinkedHashMap before serializing.
- Avoid storing Gson internal map types in serializable fields.
When it happens
Trigger: Calling ObjectInputStream.readObject() on a stream whose root object is tagged as a LinkedTreeMap (bypassing writeReplace), e.g. a forged, legacy, or manually constructed stream. Normal serialization writes a LinkedHashMap and reads a LinkedHashMap, so this fires only on non-standard streams.
Common situations: Deserializing an object graph persisted by an old Gson version or a buggy custom ObjectOutputStream; tampered streams; testing tooling that constructs object streams directly; interop with another JVM language that bypasses writeReplace.
Related errors
- Deserialization is unsupported
- key == null
- value == null
- {className} is not Comparable
- JSON forbids NaN and infinities: {value}
AI-assisted analysis of google/gson@8b8628c656 (2026-08-04).
Data as JSON: /data/errors/de5890569147fcd5.json.
Report an issue: GitHub.