{"record":{"id":"f65735a25de897e2","repo":"jwtk/jjwt","slug":"compact-jwe-strings-must-always-contain-an-initial","errorCode":null,"errorMessage":"Compact JWE strings must always contain an Initialization Vector.","messagePattern":"Compact JWE strings must always contain an Initialization Vector\\.","errorType":"exception","errorClass":"MalformedJwtException","httpStatus":null,"severity":"error","filePath":"impl/src/main/java/io/jsonwebtoken/impl/DefaultJwtParser.java","lineNumber":520,"sourceCode":"            Assert.stateNotNull(keyAlg, \"JWE Key Algorithm cannot be null.\");\n\n            byte[] cekBytes = Bytes.EMPTY; //ignored unless using an encrypted key algorithm\n            CharSequence base64Url = tokenizedJwe.getEncryptedKey();\n            if (Strings.hasText(base64Url)) {\n                cekBytes = decode(base64Url, \"JWE encrypted key\");\n                if (Bytes.isEmpty(cekBytes)) {\n                    String msg = \"Compact JWE string represents an encrypted key, but the key is empty.\";\n                    throw new MalformedJwtException(msg);\n                }\n            }\n\n            base64Url = tokenizedJwe.getIv();\n            if (Strings.hasText(base64Url)) {\n                iv = decode(base64Url, \"JWE Initialization Vector\");\n            }\n            if (Bytes.isEmpty(iv)) {\n                String msg = \"Compact JWE strings must always contain an Initialization Vector.\";\n                throw new MalformedJwtException(msg);\n            }\n\n            // The AAD (Additional Authenticated Data) scheme for compact JWEs is to use the ASCII bytes of the\n            // raw base64url text as the AAD, and NOT the base64url-decoded bytes per\n            // https://www.rfc-editor.org/rfc/rfc7516.html#section-5.1, Step 14.\n            ByteBuffer buf = StandardCharsets.US_ASCII.encode(Strings.wrap(base64UrlHeader));\n            final byte[] aadBytes = new byte[buf.remaining()];\n            buf.get(aadBytes);\n            InputStream aad = Streams.of(aadBytes);\n\n            base64Url = base64UrlDigest;\n            //guaranteed to be non-empty via the `alg` + digest check above:\n            Assert.hasText(base64Url, \"JWE AAD Authentication Tag cannot be null or empty.\");\n            digest = decode(base64Url, \"JWE AAD Authentication Tag\");\n            if (Bytes.isEmpty(digest)) {\n                String msg = \"Compact JWE strings must always contain an AAD Authentication Tag.\";\n                throw new MalformedJwtException(msg);\n            }","sourceCodeStart":502,"sourceCodeEnd":538,"githubUrl":"https://github.com/jwtk/jjwt/blob/fb71496164c71442d08adec4571d9616ed5e1b8d/impl/src/main/java/io/jsonwebtoken/impl/DefaultJwtParser.java#L502-L538","documentation":"RFC 7516 requires every compact JWE to carry an Initialization Vector, so after decoding the 'iv' segment the parser checks it decoded to non-empty bytes; if the segment is absent or empty it throws MalformedJwtException because AEAD decryption cannot proceed without an IV.","triggerScenarios":"Parsing a compact JWE that omits the IV segment, has an empty third component, or whose IV text fails to decode to bytes (e.g. a JWS string mistakenly passed to JWE parsing).","commonSituations":"Passing a JWS (3 or 4 parts, no IV) into a JWE parse path, tokens truncated after the ciphertext start, hand-assembled JWE strings missing the '.' separators.","solutions":["Ensure you are parsing the right token type: JWS strings have no IV; use the JWS API for them.","Regenerate the JWE with a valid producer so the IV segment is populated (all standard JWE enc modes always emit an IV).","Check the compact string has exactly 5 parts and the 3rd part is non-empty base64url.","If truncation is suspected, re-fetch the token from the issuer instead of repairing it."],"exampleFix":"// before (JWS fed to JWE parser)\nJwt<Header,String> jwe = parser.parse(jwsString);\n// after\nJws<Claims> jws = Jwts.parser().verifyWith(key).build().parseSignedClaims(jwsString);","handlingStrategy":"validation","validationCode":"String[] parts = jwe.split(\"\\\\.\", -1);\nboolean looksLikeJwe = parts.length == 5 && !parts[2].isEmpty();\nif (!looksLikeJwe) throw new IllegalArgumentException(\"Not a compact JWE (missing IV segment)\");","typeGuard":null,"tryCatchPattern":"try { parser.parse(token); } catch (MalformedJwtException e) { if (e.getMessage().contains(\"Initialization Vector\")) { /* route to JWS parser or reject */ } }","preventionTips":["Distinguish JWS vs JWE token types before choosing the parser API.","Always confirm the 3rd segment of a JWE is non-empty base64url.","Avoid manual string manipulation of tokens; pass the original string end-to-end.","Test token round-trips (issue -> parse) in CI to catch producer regressions."],"tags":["jwe","iv","malformed-jwt","aead"],"backgroundTag":"invalid-argument-format","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"}