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

  1. Remove the encodePayload(false) call when building encrypted or unprotected JWTs, and let the payload be encoded.
  2. If unencoded payload is required, build a JWS instead of a JWE.
  3. Gate the encodePayload(false) call behind the same condition that selects JWS output.
  4. 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

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


AI-assisted analysis of jwtk/jjwt@fb71496164 (2026-09-09). Data as JSON: /api/errors/919e46b74673fbd4. Report an issue: GitHub.