{"record":{"id":"d64cea31942f34fc","repo":"jwtk/jjwt","slug":"unexpected-claims-jws","errorCode":null,"errorMessage":"Unexpected Claims JWS.","messagePattern":"Unexpected Claims JWS\\.","errorType":"exception","errorClass":"UnsupportedJwtException","httpStatus":null,"severity":"error","filePath":"api/src/main/java/io/jsonwebtoken/SupportedJwtVisitor.java","lineNumber":144,"sourceCode":"     * @throws UnsupportedJwtException by default, expecting the subclass implementation to override as necessary.\n     */\n    public T onVerifiedContent(Jws<byte[]> jws) {\n        throw new UnsupportedJwtException(\"Unexpected content JWS.\");\n    }\n\n    /**\n     * Handles an encountered JWS message that has been cryptographically verified/authenticated and has a\n     * {@link Claims} payload.\n     *\n     * <p>The default implementation immediately throws an {@link UnsupportedJwtException}; it is expected that\n     * subclasses will override this method if the application needs to support this type of JWT.</p>\n     *\n     * @param jws the parsed signed (and verified) Claims JWS\n     * @return any object to be used after inspecting the JWS, or {@code null} if no return value is necessary.\n     * @throws UnsupportedJwtException by default, expecting the subclass implementation to override as necessary.\n     */\n    public T onVerifiedClaims(Jws<Claims> jws) {\n        throw new UnsupportedJwtException(\"Unexpected Claims JWS.\");\n    }\n\n    /**\n     * Handles an encountered JSON Web Encryption (aka 'JWE') message that has been authenticated and decrypted by\n     * delegating to either {@link #onDecryptedContent(Jwe)} or {@link #onDecryptedClaims(Jwe)} depending on the\n     * payload type.\n     *\n     * @param jwe the parsed authenticated and decrypted JWE.\n     * @return the value returned by either {@link #onDecryptedContent(Jwe)} or {@link #onDecryptedClaims(Jwe)}\n     * depending on the payload type.\n     * @throws UnsupportedJwtException if the payload is neither a {@code byte[]} nor {@code Claims}, or either\n     *                                 delegate method throws the same.\n     */\n    @SuppressWarnings(\"unchecked\")\n    @Override\n    public T visit(Jwe<?> jwe) {\n        Assert.notNull(jwe, \"JWE cannot be null.\");\n        Object payload = jwe.getPayload();","sourceCodeStart":126,"sourceCodeEnd":162,"githubUrl":"https://github.com/jwtk/jjwt/blob/fb71496164c71442d08adec4571d9616ed5e1b8d/api/src/main/java/io/jsonwebtoken/SupportedJwtVisitor.java#L126-L162","documentation":"SupportedJwtVisitor.onVerifiedClaims is the default callback for a JWS that has been cryptographically verified and whose payload is a Claims JSON object. The base class throws UnsupportedJwtException by default, expecting a subclass to override this method. Hitting it means your parser dispatched a verified Claims JWS to a visitor that does not handle that token type.","triggerScenarios":"Parsing a properly signed token containing a Claims payload (e.g. created with Jwts.builder().claims()...signWith(key)) through a parser/visitor that does not override onVerifiedClaims — for example a visitor written only for content JWSs or JWEs.","commonSituations":"Custom visitor subclasses that only implemented some callbacks; refactors where parse() (visitor-dispatch) replaced parseClaimsJws() but the visitor was never extended; shared generic parsing pipelines receiving Claims JWSs they never anticipated.","solutions":["Override onVerifiedClaims in your SupportedJwtVisitor subclass to inspect and return data from Jws<Claims>.","Confirm the parse call matches the token type (use parseClaimsJws or equivalent instead of a generic visitor parse if Claims are the target).","If Claims JWSs are not supported in this code path, reject the token upstream before parsing.","Add a test that parses a signed Claims token through the visitor to catch missing overrides early."],"exampleFix":"// before\npublic class ContentOnlyVisitor extends SupportedJwtVisitor<MyType> {\n    @Override public MyType onVerifiedContent(Jws<byte[]> jws) { return handle(jws); }\n    // onVerifiedClaims not overridden -> throws\n}\n// after\npublic class ContentOnlyVisitor extends SupportedJwtVisitor<MyType> {\n    @Override public MyType onVerifiedContent(Jws<byte[]> jws) { return handle(jws); }\n    @Override public MyType onVerifiedClaims(Jws<Claims> jws) { return handleClaims(jws.getPayload()); }\n}","handlingStrategy":"try-catch","validationCode":"// Ensure the visitor subclass overrides onVerifiedClaims before wiring it into the parser\nClass<? extends SupportedJwtVisitor<?>> c = visitor.getClass();\nboolean overridden = !SupportedJwtVisitor.class.equals(\n    c.getMethod(\"onVerifiedClaims\", Jws.class).getDeclaringClass());","typeGuard":"boolean visitorHandlesClaimsJws(SupportedJwtVisitor<?> v) {\n    try {\n        return !SupportedJwtVisitor.class.equals(\n            v.getClass().getMethod(\"onVerifiedClaims\", Jws.class).getDeclaringClass());\n    } catch (NoSuchMethodException e) { return false; }\n}","tryCatchPattern":"try {\n    Jws<Claims> jws = Jwts.parser().verifyWith(key).build().parseSignedClaims(token);\n} catch (UnsupportedJwtException e) {\n    log.warn(\"Verified Claims JWS dispatched to a visitor without onVerifiedClaims\", e);\n    throw new SecurityException(\"Claims JWS not supported by this visitor\", e);\n}","preventionTips":["Never instantiate SupportedJwtVisitor directly; always subclass and override the callbacks you expect","Prefer typed parse methods (parseSignedClaims) over generic visitor dispatch when the token type is known","Add a smoke test parsing a signed Claims token through each visitor in production use","Review visitor subclasses when adding new token types to the system"],"tags":["java","jwt","jjwt","jws","claims","unsupported-jwt"],"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"}