{"record":{"id":"f4eb9d7807dfd0cc","repo":"jwtk/jjwt","slug":"the-jwt-header-references-compression-algorithm","errorCode":null,"errorMessage":"The JWT header references compression algorithm '%s', but payload decompression for Unencoded JWSs (those with a b64 header value of false) that rely on a SigningKeyResolver are disallowed by default to protect against [Denial of Service attacks](https://www.usenix.org/system/files/conference/usenixsecurity15/sec15-paper-pellegrino.pdf).  If you wish to enable Unencoded JWS payload decompression, configure the JwtParserBuilder.keyLocator(Locator) and do not configure a SigningKeyResolver.","messagePattern":"The JWT header references compression algorithm '%s', but payload decompression for Unencoded JWSs \\(those with a b64 header value of false\\) that rely on a SigningKeyResolver are disallowed by default to protect against \\[Denial of Service attacks\\]\\(https://www\\.usenix\\.org/system/files/conference/usenixsecurity15/sec15-paper-pellegrino\\.pdf\\)\\.  If you wish to enable Unencoded JWS payload decompression, configure the JwtParserBuilder\\.keyLocator\\(Locator\\) and do not configure a SigningKeyResolver\\.","errorType":"exception","errorClass":"UnsupportedJwtException","httpStatus":null,"severity":"error","filePath":"impl/src/main/java/io/jsonwebtoken/impl/DefaultJwtParser.java","lineNumber":586,"sourceCode":"            encAlg.decrypt(dreq, plaintext);\n            payload = new Payload(plaintext.toByteArray(), header.getContentType());\n\n            integrityVerified = true; // AEAD performs integrity verification, so no exception = verified\n\n        } else if (hasDigest && this.signingKeyResolver == null) { //TODO: for 1.0, remove the == null check\n            // not using a signing key resolver, so we can verify the signature before reading the payload, which is\n            // always safer:\n            JwsHeader jwsHeader = Assert.stateIsInstance(JwsHeader.class, header, \"Not a JwsHeader. \");\n            digest = verifySignature(tokenized, jwsHeader, alg, new LocatingKeyResolver(this.keyLocator), null, payload);\n            integrityVerified = true; // no exception means signature verified\n        }\n\n        final CompressionAlgorithm compressionAlgorithm = zipAlgs.apply(header);\n        if (compressionAlgorithm != null) {\n            if (!integrityVerified) {\n                if (!payloadBase64UrlEncoded) {\n                    String msg = String.format(B64_DECOMPRESSION_MSG, compressionAlgorithm.getId());\n                    throw new UnsupportedJwtException(msg);\n                } else if (!unsecuredDecompression) {\n                    String msg = String.format(UNPROTECTED_DECOMPRESSION_MSG, compressionAlgorithm.getId());\n                    throw new UnsupportedJwtException(msg);\n                }\n            }\n            payload = payload.decompress(compressionAlgorithm);\n        }\n\n        Claims claims = null;\n        byte[] payloadBytes = payload.getBytes();\n        if (payload.isConsumable()) {\n            InputStream in = null;\n            try {\n                in = payload.toInputStream();\n\n                if (!hasContentType(header)) {   // If there is a content type set, then the application using JJWT is expected\n                    //                          to convert the byte payload themselves based on this content type\n                    //                          https://www.rfc-editor.org/rfc/rfc7515.html#section-4.1.10 :","sourceCodeStart":568,"sourceCodeEnd":604,"githubUrl":"https://github.com/jwtk/jjwt/blob/fb71496164c71442d08adec4571d9616ed5e1b8d/impl/src/main/java/io/jsonwebtoken/impl/DefaultJwtParser.java#L568-L604","documentation":"For unencoded JWSs (b64=false) whose payload compression is requested, the library refuses to decompress when integrity wasn't cryptographically verified and a SigningKeyResolver is in use, because decompressing attacker-controlled data enables DoS (zip bombs). It throws UnsupportedJwtException instructing you to switch to a KeyLocator.","triggerScenarios":"Parsing an unencoded JWS (b64:false header) with a zip/def header while a SigningKeyResolver is configured and unsecuredDecompression() was not called.","commonSituations":"Legacy code using deprecated setSigningKeyResolver APIs combined with compressed unencoded payloads, migration from older JJWT versions where this was allowed, tokens produced with custom unencoded+compressed formats.","solutions":["Replace SigningKeyResolver with JwtParserBuilder.keyLocator(Locator) so integrity is verified before decompression.","Remove compression (zip header) from unencoded JWSs, or use standard encoded JWSs where decompression after verification is safe.","If you must keep the old flow and accept the risk, call .unsecuredDecompression() on the builder after reading its security JavaDoc.","Verify the token producer really needs b64:false; most use cases should not use unencoded payloads."],"exampleFix":"// before\nJwts.parser().setSigningKeyResolver(resolver).build().parse(jws);\n// after\nJwts.parser().keyLocator(header -> key).build().parse(jws);","handlingStrategy":"try-catch","validationCode":"Map<String,Object> h = getUntrustedHeader(token); // decode header without parsing payload\nboolean unsafe = h.containsKey(\"zip\") && h.containsKey(\"b64\") && Boolean.FALSE.equals(h.get(\"b64\")) && usingSigningKeyResolver;","typeGuard":null,"tryCatchPattern":"try { parser.parse(jws); } catch (UnsupportedJwtException e) { if (e.getMessage().contains(\"decompression\")) { /* migrate to keyLocator or enable explicitly */ } }","preventionTips":["Prefer keyLocator(Locator) over the deprecated SigningKeyResolver APIs.","Avoid compressing unencoded payloads; use standard encoded JWSs.","Only enable unsecuredDecompression() after reading its security JavaDoc.","Strip zip headers at the producer unless verified-token decompression is intended."],"tags":["compression","dos","unencoded-jws","signing-key-resolver"],"backgroundTag":"feature-not-enabled","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"}