{"id":"de5890569147fcd5","repo":"google/gson","slug":"deserialization-is-unsupported-de5890","errorCode":null,"errorMessage":"Deserialization is unsupported","messagePattern":"Deserialization is unsupported","errorType":"exception","errorClass":"InvalidObjectException","httpStatus":null,"severity":"error","filePath":"gson/src/main/java/com/google/gson/internal/LinkedTreeMap.java","lineNumber":675,"sourceCode":"    @Override\n    public void clear() {\n      LinkedTreeMap.this.clear();\n    }\n  }\n\n  /**\n   * If somebody is unlucky enough to have to serialize one of these, serialize it as a\n   * LinkedHashMap so that they won't need Gson on the other side to deserialize it. Using\n   * serialization defeats our DoS defence, so most apps shouldn't use it.\n   */\n  private Object writeReplace() throws ObjectStreamException {\n    return new LinkedHashMap<>(this);\n  }\n\n  private void readObject(ObjectInputStream in) throws IOException {\n    // Don't permit directly deserializing this class; writeReplace() should have written a\n    // replacement\n    throw new InvalidObjectException(\"Deserialization is unsupported\");\n  }\n}\n","sourceCodeStart":657,"sourceCodeEnd":678,"githubUrl":"https://github.com/google/gson/blob/8b8628c65699bc4421696183c62ae0c1b9b281dc/gson/src/main/java/com/google/gson/internal/LinkedTreeMap.java#L657-L678","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\nObjectOutputStream out = ...\nout.writeObject(linkedTreeMap); // internal type\nObjectInputStream in = ...\nMap<?,?> m = (Map<?,?>) in.readObject(); // InvalidObjectException\n\n// after: serialize as a standard map or JSON\nout.writeObject(new LinkedHashMap<>(linkedTreeMap));","handlingStrategy":"try-catch","validationCode":"// Convert to a portable map before Java serialization\nstatic Map<?, ?> portable(Map<?, ?> m) {\n  return new LinkedHashMap<>(m);\n}\n// usage: out.writeObject(portable(linkedTreeMap));","typeGuard":"static boolean isJavaSerializableMap(Object o) {\n  return o instanceof LinkedHashMap || o instanceof HashMap;\n}","tryCatchPattern":"try {\n  Object o = in.readObject();\n} catch (InvalidObjectException e) {\n  if (e.getMessage().contains(\"Deserialization is unsupported\")) {\n    // switch to JSON-based persistence\n    throw new IllegalStateException(\"Persist via Gson JSON, not Java serialization\", e);\n  } else throw e;\n}","preventionTips":["Do not Java-serialize LinkedTreeMap; use JSON transport.","Copy entries into LinkedHashMap before serializing.","Avoid storing Gson internal map types in serializable fields."],"tags":["gson","serialization","internal","linkedtreemap","invalidobjectexception"],"analyzedSha":"8b8628c65699bc4421696183c62ae0c1b9b281dc","analyzedAt":"2026-08-04T19:12:22.202Z","schemaVersion":2}