{"record":{"id":"5cd45bb94b53ff57","repo":"jwtk/jjwt","slug":"unable-to-serialize-object-of-type-classname","errorCode":null,"errorMessage":"Unable to serialize object of type ${className}: ${e.getMessage()}","messagePattern":"Unable to serialize object of type (.+?): (.+?)","errorType":"exception","errorClass":"SerializationException","httpStatus":null,"severity":"error","filePath":"api/src/main/java/io/jsonwebtoken/io/AbstractSerializer.java","lineNumber":60,"sourceCode":"    public final byte[] serialize(T t) throws SerializationException {\n        ByteArrayOutputStream out = new ByteArrayOutputStream();\n        serialize(t, out);\n        return out.toByteArray();\n    }\n\n    /**\n     * {@inheritDoc}\n     */\n    @Override\n    public final void serialize(T t, OutputStream out) throws SerializationException {\n        try {\n            doSerialize(t, out);\n        } catch (Throwable e) {\n            if (e instanceof SerializationException) {\n                throw (SerializationException) e;\n            }\n            String msg = \"Unable to serialize object of type \" + Objects.nullSafeClassName(t) + \": \" + e.getMessage();\n            throw new SerializationException(msg, e);\n        }\n    }\n\n    /**\n     * Converts the specified Java object into a formatted data byte stream, writing the bytes to the specified\n     * {@code out}put stream.\n     *\n     * @param t   the object to convert to a byte stream\n     * @param out the stream to write to\n     * @throws Exception if there is a problem converting the object to a byte stream or writing the\n     *                   bytes to the {@code out}put stream.\n     * @since 0.12.0\n     */\n    protected abstract void doSerialize(T t, OutputStream out) throws Exception;\n}\n","sourceCodeStart":42,"sourceCodeEnd":76,"githubUrl":"https://github.com/jwtk/jjwt/blob/fb71496164c71442d08adec4571d9616ed5e1b8d/api/src/main/java/io/jsonwebtoken/io/AbstractSerializer.java#L42-L76","documentation":"JJWT wraps any unexpected Throwable thrown while serializing an object (typically the JWT claim map) into bytes into a SerializationException. AbstractSerializer.serialize catches failures from doSerialize that are not already SerializationException instances and rethrows them with the object's class name and the underlying message. The class name in the message tells you exactly which object failed to convert.","triggerScenarios":"Serializing a claims map or payload containing a value the underlying JSON runtime cannot handle — e.g. an object with no Jackson/Gson serializer, a JDK type the runtime rejects, circular object references, or a custom Serializer whose doSerialize throws (IOException, IllegalArgumentException, etc.).","commonSituations":"Putting non-JSON-friendly values in claims (Date handled by default, but custom types like BufferedImage, Hibernate lazy proxies, or enums without registered serializers); Jackson failing with 'No serializer found' due to no getters and visibility config; classpath version mismatch between JJWT and Jackson/Gson; a custom Serializer that throws raw exceptions.","solutions":["Read the cause and the class name in the message; ensure that type is JSON-serializable by the configured runtime (Jackson or Gson)","Simplify claim values to primitives, Strings, Dates, Maps, and Lists, or register a serializer/converter for the custom type","Fix Jackson visibility issues (add getters or @JsonProperty/@JsonAutoDetect) when 'No serializer found' is the cause","If you implemented a custom Serializer, wrap failures in SerializationException inside doSerialize so they propagate unchanged"],"exampleFix":"// before\njws = Jwts.builder().setClaims(Map.of(\"user\", hibernateLazyProxy)).compact();\n// Unable to serialize object of type User$HibernateProxy$...: ...\n\n// after\njws = Jwts.builder().claim(\"userId\", user.getId()).compact(); // serialize plain values","handlingStrategy":"validation","validationCode":"// Java: ensure claim values are JSON-safe before building the JWT\nstatic boolean isJsonSafe(Object v) {\n    if (v == null) return true;\n    if (v instanceof String || v instanceof Number || v instanceof Boolean) return true;\n    if (v instanceof java.util.Date || v instanceof java.util.Calendar) return true;\n    if (v instanceof Map<?,?> m) return m.values().stream().allMatch(MyClaims::isJsonSafe);\n    if (v instanceof java.util.Collection<?> c) return c.stream().allMatch(MyClaims::isJsonSafe);\n    if (v instanceof byte[] || v instanceof char[]) return true;\n    return false;\n}","typeGuard":"boolean isSerializableClaim(Object v) {\n    return v == null || v instanceof String || v instanceof Number\n        || v instanceof Boolean || v instanceof java.util.Date\n        || v instanceof Map || v instanceof java.util.Collection;\n}","tryCatchPattern":"try {\n    String jws = Jwts.builder().setClaims(claims).signWith(key).compact();\n} catch (SerializationException e) {\n    // e.getCause() holds the underlying serializer failure\n}","preventionTips":["Restrict claim values to primitives, Strings, Dates, Maps, and Lists","Never place lazy ORM proxies or framework-managed entities directly into claims","Register Jackson serializers/modules for any custom types you must include","Verify getters/visibility for beans serialized by Jackson (avoid 'No serializer found')","Wrap failures in SerializationException inside any custom Serializer's doSerialize"],"tags":["serialization","json","jwt"],"backgroundTag":"json-marshal-failed","analyzedSha":"fb71496164c71442d08adec4571d9616ed5e1b8d","analyzedAt":"2026-09-09T00:33:09.982Z","contentChangedAt":"2026-09-09T00:33:09.982Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}