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
- Add .enableUnsecured() alongside the unsecuredDecompression flag if you truly need to accept unsecured tokens
- Remove the unsecuredDecompression call if you never accept unsecured (unsigned) JWTs — this is the safest fix
- 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
- Never enable unsecured features unless legacy unsigned tokens must be accepted
- Read the JavaDoc security notes before enabling decompression features
- Keep feature-flag toggles paired in configuration code
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
- Both 'zip()' and 'compressionCodecResolver' cannot be config
- JWT signature does not match locally computed signature. JWT
- The parsed JWT indicates it was signed with the '${algId}' s
- Unsecured JWSs (those with an alg header value of 'none') ar
- PrivateKeys may not be used to verify digital signatures. Pr
AI-assisted analysis of jwtk/jjwt@fb71496164 (2026-09-09).
Data as JSON: /api/errors/e21a140e62c44d76.
Report an issue: GitHub.