jwtk/jjwt · error · UnsupportedJwtException
Unexpected Claims JWE.
Error message
Unexpected Claims JWE.
What it means
SupportedJwtVisitor.onDecryptedClaims is the default callback for a JWE that has been authenticated, decrypted, and whose payload is a Claims JSON object. The base implementation throws UnsupportedJwtException, expecting subclasses to override it. Hitting it means a decrypted Claims JWE was dispatched to a visitor that does not implement handling for that token type.
Source
Thrown at api/src/main/java/io/jsonwebtoken/SupportedJwtVisitor.java:198
* @return any object to be used after inspecting the JWS, or {@code null} if no return value is necessary.
* @throws UnsupportedJwtException by default, expecting the subclass implementation to override as necessary.
*/
public T onDecryptedContent(Jwe<byte[]> jwe) {
throw new UnsupportedJwtException("Unexpected content JWE.");
}
/**
* Handles an encountered JWE message that has been authenticated and decrypted, and has a {@link Claims} payload.
*
* <p>The default implementation immediately throws an {@link UnsupportedJwtException}; it is expected that
* subclasses will override this method if the application needs to support this type of JWT.</p>
*
* @param jwe the parsed authenticated and decrypted content JWE.
* @return any object to be used after inspecting the JWE, or {@code null} if no return value is necessary.
* @throws UnsupportedJwtException by default, expecting the subclass implementation to override as necessary.
*/
public T onDecryptedClaims(Jwe<Claims> jwe) {
throw new UnsupportedJwtException("Unexpected Claims JWE.");
}
}
View on GitHub (pinned to fb71496164)
Solutions
- Override onDecryptedClaims in your SupportedJwtVisitor subclass to process Jwe<Claims> and return the desired value.
- Ensure the parser is configured with the correct decryption key and algorithms so the JWE decrypts and dispatches correctly.
- If Claims JWEs are not expected, reject them before parsing or filter by the token's header (typ/enc).
- Add tests covering encrypted Claims tokens to catch unimplemented visitor callbacks.
Example fix
// before
public class JwsOnlyVisitor extends SupportedJwtVisitor<MyType> {
@Override public MyType onVerifiedClaims(Jws<Claims> jws) { return handle(jws.getPayload()); }
// onDecryptedClaims not overridden -> throws on JWE
}
// after
public class JwsOnlyVisitor extends SupportedJwtVisitor<MyType> {
@Override public MyType onVerifiedClaims(Jws<Claims> jws) { return handle(jws.getPayload()); }
@Override public MyType onDecryptedClaims(Jwe<Claims> jwe) { return handle(jwe.getPayload()); }
} Defensive patterns
Strategy: try-catch
Validate before calling
// Confirm the token is a 5-part JWE (encrypted Claims possible) before visitor dispatch
String[] parts = compact.split("\\.", -1);
boolean encryptedClaimsCandidate = parts.length == 5;
if (encryptedClaimsCandidate && !visitorHandlesDecryptedClaims) {
throw new IllegalArgumentException("Encrypted Claims JWE not supported by this handler");
} Type guard
boolean visitorHandlesDecryptedClaims(SupportedJwtVisitor<?> v) {
try {
return !SupportedJwtVisitor.class.equals(
v.getClass().getMethod("onDecryptedClaims", Jwe.class).getDeclaringClass());
} catch (NoSuchMethodException e) { return false; }
} Try / catch
try {
Jwe<Claims> jwe = Jwts.parser().decryptWith(key).build().parseEncryptedClaims(token);
} catch (UnsupportedJwtException e) {
log.warn("Decrypted Claims JWE dispatched to a visitor without onDecryptedClaims", e);
throw new SecurityException("Claims JWE not supported by this visitor", e);
} Prevention
- Override onDecryptedClaims whenever encrypted claims tokens are part of your flows
- Prefer parseEncryptedClaims when the token type is known instead of generic visitor parsing
- Test visitors against all four token shapes: unsecured, JWS, JWE, claims vs content payloads
- Keep a checklist of SupportedJwtVisitor callbacks to override when adding new token types
When it happens
Trigger: Parsing an encrypted token whose plaintext payload is Claims (built with Jwts.builder().claims()...encryptWith(...)) via a parser whose visitor lacks an onDecryptedClaims override; decryption succeeds, then the dispatch throws.
Common situations: Consumers migrating from signed Claims JWS to encrypted Claims JWE whose visitors only overrode onVerifiedClaims; shared parsing infrastructure that handles JWS but not JWE; omitted override after adding encryption to a token flow.
Understand the failure class
Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.
Related errors
- Unexpected Claims JWS.
- Unexpected content JWE.
- Unexpected unsecured Claims JWT.
- Unexpected content JWS.
- The '${id}' algorithm requires keys with a length of ${bitsM
AI-assisted analysis of jwtk/jjwt@fb71496164 (2026-09-09).
Data as JSON: /api/errors/f26c3fb314aba12f.
Report an issue: GitHub.