{"record":{"id":"428816e4c927d8c1","repo":"jwtk/jjwt","slug":"string-format-malformed-complex-error-this-name","errorCode":null,"errorMessage":"${String.format(MALFORMED_COMPLEX_ERROR, this.name, this.name, e.getMessage())}","messagePattern":"\\$\\{String\\.format\\(MALFORMED_COMPLEX_ERROR, this\\.name, this\\.name, e\\.getMessage\\(\\)\\)\\}","errorType":"exception","errorClass":"DeserializationException","httpStatus":null,"severity":"error","filePath":"impl/src/main/java/io/jsonwebtoken/impl/io/JsonObjectDeserializer.java","lineNumber":70,"sourceCode":"            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\n    protected RuntimeException malformed(Throwable t) {\n        String msg = String.format(MALFORMED_ERROR, this.name, t.getMessage());\n        throw new MalformedJwtException(msg, t);\n    }\n}\n","sourceCodeStart":52,"sourceCodeEnd":79,"githubUrl":"https://github.com/jwtk/jjwt/blob/fb71496164c71442d08adec4571d9616ed5e1b8d/impl/src/main/java/io/jsonwebtoken/impl/io/JsonObjectDeserializer.java#L52-L79","documentation":"Thrown as a DeserializationException when deserializing a JSON structure causes a StackOverflowError. jjwt catches this specifically because deeply nested JSON payloads (e.g. thousands of '[' or '{' characters) overflow the recursive parser and would otherwise crash the JVM thread. The formatted message names the value being parsed ('MALFORMED_COMPLEX_ERROR') and the underlying cause.","triggerScenarios":"Parsing a JWT whose payload or claims map contains extremely deeply nested JSON arrays/objects, so the streaming JSON deserializer recurses past the stack limit. Triggered via Jwts.parser().parse... on a maliciously or accidentally crafted token.","commonSituations":"Receiving untrusted JWTs from third parties; security fuzzing; logging giant nested payloads; test suites checking malformed-token handling.","solutions":["Treat the token as malformed and reject it — do not retry; the input is the problem.","Validate token structure (e.g. limit payload size and nesting) before passing it to the parser.","Increase thread stack size (-Xss) only as a stopgap; prefer rejecting the input.","Catch DeserializationException (or MalformedJwtException's superclass JwtException) and return 4xx to the caller."],"exampleFix":"// before\nClaims c = Jwts.parser().verifyWith(key).build().parseSignedClaims(token).getPayload(); // DeserializationException on deep nesting\n// after\ntry {\n    Claims c = Jwts.parser().verifyWith(key).build().parseSignedClaims(token).getPayload();\n} catch (MalformedJwtException e) {\n    throw new BadJwtTokenException(\"Malformed JWT payload\", e);\n}","handlingStrategy":"try-catch","validationCode":"// reject tokens with suspiciously large or deep payloads before parsing\nif (token.length() > MAX_TOKEN_LENGTH) throw new BadJwtTokenException(\"JWT too large\");","typeGuard":"// verify the compact JWT has exactly 3-5 dot-separated base64url segments\nboolean wellFormed = token != null && token.matches(\"^[A-Za-z0-9_-]+(\\\\.[A-Za-z0-9_-]+){2,4}$\");","tryCatchPattern":"try {\n    return Jwts.parser().verifyWith(key).build().parseSignedClaims(token);\n} catch (MalformedJwtException | DeserializationException e) {\n    throw new BadJwtTokenException(\"Malformed JWT\", e);\n}","preventionTips":["Treat untrusted JWTs as hostile; cap payload size","Catch JwtException subtypes at the authentication boundary","Never retry parsing a token that failed deserialization","Keep jjwt updated for parser hardening fixes"],"tags":["jwt","json","deserialization","security"],"backgroundTag":"json-parse-error","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"}