jwtk/jjwt · error · java.lang.IllegalStateException

'unsecuredDecompression' is only relevant if 'unsecured' is

Error message

'unsecuredDecompression' is only relevant if 'unsecured' is also configured. Please read the JavaDoc of both features before enabling either due to their security implications.

What it means

The 'unsecuredDecompression' parser feature (allowing decompression of unsecured/JWS payload parts) only has meaning when 'unsecured' tokens are also accepted. Enabling it alone is treated as a misconfiguration, so build() throws IllegalStateException with a warning to read the JavaDoc of both features because they carry security implications (decompression bombs, accepting unsigned tokens).

Source

Thrown at impl/src/main/java/io/jsonwebtoken/impl/DefaultJwtParserBuilder.java:398

                throw new IllegalStateException(msg);
            }
            if (this.decryptionKey != null) {
                String msg = "Both 'keyLocator' and a 'decryptWith' key cannot be configured. " +
                        "Prefer 'keyLocator' if possible.";
                throw new IllegalStateException(msg);
            }
        }

        Locator<? extends Key> keyLocator = this.keyLocator; // user configured default, don't overwrite to ensure further build() calls work as expected
        if (keyLocator == null) {
            keyLocator = new ConstantKeyLocator(this.signatureVerificationKey, this.decryptionKey);
        }

        if (!unsecured && unsecuredDecompression) {
            String msg = "'unsecuredDecompression' is only relevant if 'unsecured' is also " +
                    "configured. Please read the JavaDoc of both features before enabling either " +
                    "due to their security implications.";
            throw new IllegalStateException(msg);
        }
        if (this.compressionCodecResolver != null && !Jwts.ZIP.get().equals(this.zipAlgs)) {
            String msg = "Both 'zip()' and 'compressionCodecResolver' " +
                    "cannot be configured. Choose either.";
            throw new IllegalStateException(msg);
        }

        // Invariants.  If these are ever violated, it's an error in this class implementation:
        Assert.stateNotNull(keyLocator, "Key locator should never be null.");

        final DefaultClaims expClaims = (DefaultClaims) this.expectedClaims.build();

        return new DefaultJwtParser(
                provider,
                signingKeyResolver,
                unsecured,
                unsecuredDecompression,
                keyLocator,

View on GitHub (pinned to fb71496164)

Solutions

  1. Add .enableUnsecured() alongside the unsecuredDecompression flag if you truly need to accept unsecured tokens
  2. Remove the unsecuredDecompression call if you never accept unsecured (unsigned) JWTs — this is the safest fix
  3. Read the JavaDoc of both features and confirm the security trade-offs before enabling either

Example fix

// before
JwtParser parser = Jwts.parser()
    .enableUnsecuredDecompression()
    .build();
// after
JwtParser parser = Jwts.parser()
    .enableUnsecured()
    .enableUnsecuredDecompression()
    .build();
Defensive patterns

Strategy: validation

Validate before calling

boolean unsecured = false; boolean unsecuredDecompression = true;
if (unsecuredDecompression && !unsecured) {
    throw new IllegalArgumentException("unsecuredDecompression requires enableUnsecured()");
}

Try / catch

try {
    JwtParser p = builder.build();
} catch (IllegalStateException e) {
    log.error("Inconsistent parser feature flags: {}", e.getMessage());
}

Prevention

When it happens

Trigger: Calling .enableUnsecuredDecompression() (or equivalent) without calling .enableUnsecured() on DefaultJwtParserBuilder before build().

Common situations: Copy-pasting hardening/compatibility snippets from documentation or Stack Overflow that enable decompression for unsecured tokens; turning on decompression support to fix a parsing failure without realizing it requires the 'unsecured' flag too.

Understand the failure class

Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.

Related errors


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