{"record":{"id":"3b2c35f75e1b525c","repo":"hibernate/hibernate-orm","slug":"could-not-deserialize","errorCode":null,"errorMessage":"could not deserialize","messagePattern":"could not deserialize","errorType":"exception","errorClass":"SerializationException","httpStatus":null,"severity":"error","filePath":"hibernate-core/src/main/java/org/hibernate/internal/util/SerializationHelper.java","lineNumber":205,"sourceCode":"\t}\n\n\tpublic static <T> T doDeserialize(\n\t\t\tInputStream inputStream,\n\t\t\tClassLoader loader,\n\t\t\tClassLoader fallbackLoader1,\n\t\t\tClassLoader fallbackLoader2) throws SerializationException {\n\t\tif ( inputStream == null ) {\n\t\t\tthrow new IllegalArgumentException( \"The InputStream must not be null\" );\n\t\t}\n\n\t\tCORE_LOGGER.trace( \"Starting deserialization of object\" );\n\n\t\ttry ( var in = new CustomObjectInputStream( inputStream, loader, fallbackLoader1, fallbackLoader2 ) ) {\n\t\t\t//noinspection unchecked\n\t\t\treturn (T) in.readObject();\n\t\t}\n\t\tcatch (ClassNotFoundException | IOException e) {\n\t\t\tthrow new SerializationException( \"could not deserialize\", e );\n\t\t}\n\t}\n\n\t/**\n\t * Deserializes an object from an array of bytes using the\n\t * Thread Context ClassLoader (TCCL). If there is no TCCL set,\n\t * the classloader of the calling class is used.\n\t * <p>\n\t * Delegates to {@link #deserialize(byte[], ClassLoader)}\n\t *\n\t * @param objectData the serialized object, must not be null\n\t *\n\t * @return the deserialized object\n\t *\n\t * @throws IllegalArgumentException if <code>objectData</code> is <code>null</code>\n\t * @throws SerializationException (runtime) if the serialization fails\n\t */\n\tpublic static Object deserialize(byte[] objectData) throws SerializationException {","sourceCodeStart":187,"sourceCodeEnd":223,"githubUrl":"https://github.com/hibernate/hibernate-orm/blob/fad1729dce015f908198d57a8d80274a30f905a5/hibernate-core/src/main/java/org/hibernate/internal/util/SerializationHelper.java#L187-L223","documentation":"Deserialization wraps CustomObjectInputStream.readObject failures: ClassNotFoundException (the stream references a class invisible to the supplied and fallback classloaders) and IOException subtypes (StreamCorruptedException for bytes that are not a Java serialization stream, InvalidClassException for serialVersionUID/version drift, truncated input). All become SerializationException with this message; the precise reason is on the cause chain.","triggerScenarios":"deserialize()/doDeserialize on bytes not produced by Java serialization; entity classes renamed, moved, or loaded by a different classloader than the one used to write the blob; serialVersionUID changed between write and read; byte arrays truncated or sliced at the wrong offset.","commonSituations":"Serialized LOB columns read after refactoring package names; app-server redeploys where the writing classloader differs from the reading one; data written by another serializer (JSON, Kryo) passed to the Java deserializer; blobs extracted with wrong offsets from a composite payload.","solutions":["Inspect the cause: ClassNotFoundException -> make the class visible to the reading classloader or pass the right loader explicitly (e.g., Thread.currentThread().getContextClassLoader()); InvalidClassException -> restore/align serialVersionUID or rewrite the stored data; StreamCorruptedException -> the input is not a Java serialization stream, fix the producer or format.","Declare a fixed private static final long serialVersionUID on every class persisted in serialized form.","When classes or packages move, migrate stored blobs: read with the old mapping, write with the new."],"exampleFix":"// before\nObject o = SerializationHelper.deserialize(blobBytes, Helper.class.getClassLoader());\n// redeploy -> ClassNotFoundException -> \"could not deserialize\"\n\n// after\nClassLoader tccl = Thread.currentThread().getContextClassLoader();\nObject o = SerializationHelper.deserialize(blobBytes, tccl);","handlingStrategy":"try-catch","validationCode":"static boolean looksLikeJavaSerialization(byte[] data) {\n    return data != null && data.length >= 4\n            && (data[0] & 0xFF) == 0xAC && (data[1] & 0xFF) == 0xED && data[2] == 0 && data[3] == 5;\n}","typeGuard":null,"tryCatchPattern":"try {\n    Object o = SerializationHelper.deserialize(blobBytes, Thread.currentThread().getContextClassLoader());\n} catch (org.hibernate.type.SerializationException e) {\n    Throwable cause = e.getCause();\n    if (cause instanceof ClassNotFoundException) { /* classloader/class visibility fix */ }\n    else if (cause instanceof java.io.InvalidClassException) { /* serialVersionUID drift; re-export data */ }\n    else if (cause instanceof java.io.StreamCorruptedException) { /* bytes are not a Java serialization stream */ }\n}","preventionTips":["Declare explicit serialVersionUID on every class persisted in serialized form.","Pass the application classloader (often the TCCL) explicitly when deserializing.","Version stored serialized blobs; plan a migration step whenever classes move or rename."],"tags":["hibernate","serialization","classloader","deserialization"],"backgroundTag":"java-deserialization-failure","analyzedSha":"fad1729dce015f908198d57a8d80274a30f905a5","analyzedAt":"2026-08-22T04:13:57.527Z","schemaVersion":2},"datasetVersion":"2026-08-22T09:17:25.309Z"}