jwtk/jjwt · error · IllegalArgumentException
Payload encoding may not be disabled for s, only JWSs.
Error message
Payload encoding may not be disabled for s, only JWSs.
What it means
Disabling payload encoding (content() passthrough, encodePayload(false)) is only valid for JWSs. When building a JWE (encrypted) or unprotected JWT, an unencoded payload cannot be represented, so assertPayloadEncoding throws IllegalArgumentException.
Source
Thrown at impl/src/main/java/io/jsonwebtoken/impl/DefaultJwtBuilder.java:473
@Override
public JwtBuilder issuedAt(Date iat) {
return claims().issuedAt(iat).and();
}
@Override
public JwtBuilder setId(String jti) {
return id(jti);
}
@Override
public JwtBuilder id(String jti) {
return claims().id(jti).and();
}
private void assertPayloadEncoding(String type) {
if (!this.encodePayload) {
String msg = "Payload encoding may not be disabled for " + type + "s, only JWSs.";
throw new IllegalArgumentException(msg);
}
}
@Override
public String compact() {
final boolean jwe = this.enc != null;
if (jwe && signFunction != null) {
String msg = "Both 'signWith' and 'encryptWith' cannot be specified. Choose either one.";
throw new IllegalStateException(msg);
}
Payload payload = Assert.stateNotNull(this.payload, "Payload instance null, internal error");
final Claims claims = this.claimsBuilder.build();
if (jwe && payload.isEmpty() && Collections.isEmpty(claims)) { // JWE payload can never be empty:
String msg = "Encrypted JWTs must have either 'claims' or non-empty 'content'.";View on GitHub (pinned to fb71496164)
Solutions
- Remove the encodePayload(false) call when building encrypted or unprotected JWTs, and let the payload be encoded.
- If unencoded payload is required, build a JWS instead of a JWE.
- Gate the encodePayload(false) call behind the same condition that selects JWS output.
- Catch IllegalArgumentException and report the invalid builder combination.
Example fix
// before Jwts.builder().content(payload).encodePayload(false).encryptWith(key, alg, enc).compact(); // after Jwts.builder().content(payload).encryptWith(key, alg, enc).compact(); // payload will be encoded
Defensive patterns
Strategy: validation
Validate before calling
if (!encodePayload && (encrypting || unprotected)) throw new IllegalStateException("encodePayload(false) is JWS-only"); Try / catch
try { return builder.compact(); } catch (IllegalArgumentException e) { /* check encodePayload vs JWT type */ } Prevention
- Only call encodePayload(false) in JWS code paths
- Keep raw-content JWS builders separate from JWE builders
- Encode the toggle in config so it cannot combine with encryption
When it happens
Trigger: Calling builder.encodePayload(false) (direct unencoded content) together with encryptWith(...) or an unprotected JWT, then compact().
Common situations: Porting JWS compacting code that sets raw content to an encryption flow; toggling encodePayload off via config that also selects encryption.
Related errors
- Unexpected content JWE.
- Unexpected Claims JWE.
- PrivateKeys may not be used to encrypt data. PublicKeys are
- Both 'signWith' and 'encryptWith' cannot be specified. Choos
- Encrypted JWTs must have either 'claims' or non-empty 'conte
AI-assisted analysis of jwtk/jjwt@fb71496164 (2026-09-09).
Data as JSON: /api/errors/919e46b74673fbd4.
Report an issue: GitHub.