{"record":{"id":"cba5b85c7a02467c","repo":"jwtk/jjwt","slug":"protected-header-crit-set-references-unsupported-h","errorCode":null,"errorMessage":"Protected Header crit set references unsupported header name '%s'. Application developers expecting to support a JWT extension using header '%s' in their application code must indicate it is supported by using the JwtParserBuilder.critical method. Header: %s","messagePattern":"Protected Header crit set references unsupported header name '(.+?)'\\. Application developers expecting to support a JWT extension using header '(.+?)' in their application code must indicate it is supported by using the JwtParserBuilder\\.critical method\\. Header: (.+?)","errorType":"exception","errorClass":"UnsupportedJwtException","httpStatus":null,"severity":"error","filePath":"impl/src/main/java/io/jsonwebtoken/impl/DefaultJwtParser.java","lineNumber":449,"sourceCode":"            Set<String> supportedCrit = this.critical;\n            String b64Id = DefaultJwsHeader.B64.getId();\n            if (!unencodedPayload.isEmpty() && !this.critical.contains(b64Id)) {\n                // The application developer explicitly indicates they're using a B64 payload, so\n                // ensure that the B64 crit header is supported, even if they forgot to configure it on the\n                // parser builder:\n                supportedCrit = new LinkedHashSet<>(Collections.size(this.critical) + 1);\n                supportedCrit.add(DefaultJwsHeader.B64.getId());\n                supportedCrit.addAll(this.critical);\n            }\n            // assert any values per https://www.rfc-editor.org/rfc/rfc7515.html#section-4.1.11:\n            for (String name : crit) {\n                if (!header.containsKey(name)) {\n                    String msg = String.format(CRIT_MISSING_MSG, name, name, header);\n                    throw new MalformedJwtException(msg);\n                }\n                if (!supportedCrit.contains(name)) {\n                    String msg = String.format(CRIT_UNSUPPORTED_MSG, name, name, header);\n                    throw new UnsupportedJwtException(msg);\n                }\n            }\n        }\n\n        // =============== Payload =================\n        final CharSequence payloadToken = tokenized.getPayload();\n        Payload payload;\n        boolean integrityVerified = false; // only true after successful signature verification or AEAD decryption\n\n        // check if b64 extension enabled:\n        final boolean payloadBase64UrlEncoded = !(header instanceof JwsHeader) || ((JwsHeader) header).isPayloadEncoded();\n        if (payloadBase64UrlEncoded) {\n            // standard encoding, so decode it:\n            byte[] data = decode(payloadToken, \"payload\");\n            payload = new Payload(data, header.getContentType());\n        } else {\n            // The JWT uses the b64 extension, and we already know the parser supports that extension at this point\n            // in the code execution path because of the ----- crit ----- assertions section above as well as the","sourceCodeStart":431,"sourceCodeEnd":467,"githubUrl":"https://github.com/jwtk/jjwt/blob/fb71496164c71442d08adec4571d9616ed5e1b8d/impl/src/main/java/io/jsonwebtoken/impl/DefaultJwtParser.java#L431-L467","documentation":"For each name in a protected header's 'crit' set, the parser also requires that the application has explicitly declared support via JwtParserBuilder.critical(...). RFC 7515 mandates that crit-protected extensions must be understood; jjwt enforces this by throwing UnsupportedJwtException when a crit name is not in the parser's supported-critical set, even if the header contains the parameter.","triggerScenarios":"Parsing a token whose header contains \"crit\":[\"name\"] (with \"name\" present in the header) while the parser was built without .critical(\"name\") — common with the 'b64' unencoded-payload extension or custom extension headers.","commonSituations":"Receiving tokens using the b64/unencoded-payload extension without configuring the parser; adding custom crit headers on the producer side but not registering them in every consuming service; version upgrades where new crit extensions appear from an issuer.","solutions":["Register the extension on the parser builder: Jwts.parser().critical().add(\"name\").and() (and implement/verify its semantics).","For unencoded-payload JWSs, ensure the parser is built to accept 'b64' as critical and use parseSignedContent(byte[] payload).","Coordinate with the token issuer to confirm which crit extensions are in use and document them in all consumers.","If the extension is not needed, remove it from the token's crit set at the producer."],"exampleFix":"// before\nJwtParser p = Jwts.parser().verifyWith(key).build();\np.parseSignedClaims(token); // header has crit:[\"b64\"]\n\n// after\nJwtParser p = Jwts.parser().verifyWith(key)\n    .critical().add(\"b64\").and().build();","handlingStrategy":"validation","validationCode":"java.util.Map<String,Object> h = parseHeaderJson(token);\njava.util.Set<String> supported = java.util.Set.of(\"b64\"); // extensions you actually implement\n@SuppressWarnings(\"unchecked\") java.util.List<String> crit = (java.util.List<String>) h.get(\"crit\");\nif (crit != null && !supported.containsAll(crit)) throw new IllegalArgumentException(\"unsupported crit extensions: \" + crit);","typeGuard":null,"tryCatchPattern":"try { return parser.parse(token); }\ncatch (io.jsonwebtoken.UnsupportedJwtException e) { throw new InvalidTokenException(\"unsupported crit extension\", e); }","preventionTips":["Declare every crit extension you support via JwtParserBuilder.critical(...)","Keep the list of supported crit names in one shared constant across services","When issuers add extensions, update all consumers' parser builders","Only register extensions whose semantics you actually enforce"],"tags":["jwt","jws","crit-header","unsupported-extension"],"backgroundTag":"unsupported-operation","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"}