{"record":{"id":"b7156f01715d109e","repo":"jwtk/jjwt","slug":"deserialized-data-resulted-in-a-null-value-cannot","errorCode":null,"errorMessage":"Deserialized data resulted in a null value; cannot create Map<String,?>","messagePattern":"Deserialized data resulted in a null value; cannot create Map<String,\\?>","errorType":"validation","errorClass":"io.jsonwebtoken.io.DeserializationException","httpStatus":null,"severity":"error","filePath":"impl/src/main/java/io/jsonwebtoken/impl/io/JsonObjectDeserializer.java","lineNumber":55,"sourceCode":"            \"investigate the source further. Cause: %s\";\n\n    private final Deserializer<?> deserializer;\n    private final String name;\n\n    public JsonObjectDeserializer(Deserializer<?> deserializer, String name) {\n        this.deserializer = Assert.notNull(deserializer, \"JSON Deserializer cannot be null.\");\n        this.name = Assert.hasText(name, \"name cannot be null or empty.\");\n    }\n\n    @Override\n    public Map<String, ?> apply(Reader in) {\n        Assert.notNull(in, \"InputStream argument cannot be null.\");\n        Object value;\n        try {\n            value = this.deserializer.deserialize(in);\n            if (value == null) {\n                String msg = \"Deserialized data resulted in a null value; cannot create Map<String,?>\";\n                throw new DeserializationException(msg);\n            }\n            if (!(value instanceof Map)) {\n                String msg = \"Deserialized data is not a JSON Object; cannot create Map<String,?>\";\n                throw new DeserializationException(msg);\n            }\n            // JSON Specification requires all JSON Objects to have string-only keys.  So instead of\n            // checking that the val.keySet() has all Strings, we blindly cast to a Map<String,?>\n            // since input would rarely, if ever, have non-string keys.\n            //noinspection unchecked\n            return (Map<String, ?>) value;\n        } catch (StackOverflowError e) {\n            String msg = String.format(MALFORMED_COMPLEX_ERROR, this.name, this.name, e.getMessage());\n            throw new DeserializationException(msg, e);\n        } catch (Throwable t) {\n            throw malformed(t);\n        }\n    }\n","sourceCodeStart":37,"sourceCodeEnd":73,"githubUrl":"https://github.com/jwtk/jjwt/blob/fb71496164c71442d08adec4571d9616ed5e1b8d/impl/src/main/java/io/jsonwebtoken/impl/io/JsonObjectDeserializer.java#L37-L73","documentation":"Thrown as a DeserializationException when the JSON deserializer produces null from the input, so a Map<String,?> cannot be constructed. JsonObjectDeserializer expects deserializable JSON object content; a null result means the input was empty, literal 'null', or otherwise deserialized to nothing.","triggerScenarios":"Calling deserialize with an empty InputStream, an InputStream containing only whitespace or the JSON literal 'null', or a deserializer configured to return null for unrecognized input.","commonSituations":"Passing an empty JWT payload segment (decoded to zero bytes); reading from a stream that was already consumed; serializing a Java null claims map earlier and then trying to deserialize it back.","solutions":["Verify the input stream actually contains JSON object bytes before deserializing.","Check the stream position — ensure it was not already read/consumed elsewhere.","Ensure the producer serialized actual JSON object content, not null.","Add a caller-side check: if the decoded byte array is empty, fail before calling the deserializer."],"exampleFix":"// before\nMap<String,?> claims = deserializer.deserialize(new ByteArrayInputStream(payload));\n// after\nif (payload == null || payload.length == 0) {\n    throw new IllegalArgumentException(\"payload is empty\");\n}\nMap<String,?> claims = deserializer.deserialize(new ByteArrayInputStream(payload));","handlingStrategy":"validation","validationCode":"// Java\nif (payload == null || payload.length == 0) {\n    throw new IllegalArgumentException(\"payload must be non-empty JSON object bytes\");\n}\nString s = new String(payload, StandardCharsets.UTF_8).trim();\nif (s.isEmpty() || s.equals(\"null\")) throw new IllegalArgumentException(\"payload deserializes to null\");","typeGuard":"static boolean isNonEmptyJson(byte[] bytes) {\n    if (bytes == null || bytes.length == 0) return false;\n    String s = new String(bytes, StandardCharsets.UTF_8).trim();\n    return !s.isEmpty() && !s.equalsIgnoreCase(\"null\");\n}","tryCatchPattern":"try {\n    Map<String,?> claims = deserializer.apply(in);\n} catch (DeserializationException e) {\n    throw new IllegalArgumentException(\"Claims payload is empty or null: \" + e.getMessage());\n}","preventionTips":["Never serialize null claim maps; reject them at construction time.","Confirm stream freshness — an already-read stream yields empty bytes.","Validate the decoded payload segment is non-empty before deserialization.","Log raw payload bytes (safely) when diagnosing null deserialization results."],"tags":["json","deserialization","null"],"backgroundTag":"json-unmarshal-failed","analyzedSha":"fb71496164c71442d08adec4571d9616ed5e1b8d","analyzedAt":"2026-09-09T00:33:09.982Z","contentChangedAt":"2026-09-09T00:33:09.982Z","schemaVersion":2},"datasetVersion":"2026-09-14T11:17:12.474Z"}