{"record":{"id":"db8f49655c338b6f","repo":"jwtk/jjwt","slug":"both-zip-and-compressioncodecresolver-cannot","errorCode":null,"errorMessage":"Both 'zip()' and 'compressionCodecResolver' cannot be configured. Choose either.","messagePattern":"Both 'zip\\(\\)' and 'compressionCodecResolver' cannot be configured\\. Choose either\\.","errorType":"exception","errorClass":"java.lang.IllegalStateException","httpStatus":null,"severity":"error","filePath":"impl/src/main/java/io/jsonwebtoken/impl/DefaultJwtParserBuilder.java","lineNumber":403,"sourceCode":"                throw new IllegalStateException(msg);\n            }\n        }\n\n        Locator<? extends Key> keyLocator = this.keyLocator; // user configured default, don't overwrite to ensure further build() calls work as expected\n        if (keyLocator == null) {\n            keyLocator = new ConstantKeyLocator(this.signatureVerificationKey, this.decryptionKey);\n        }\n\n        if (!unsecured && unsecuredDecompression) {\n            String msg = \"'unsecuredDecompression' is only relevant if 'unsecured' is also \" +\n                    \"configured. Please read the JavaDoc of both features before enabling either \" +\n                    \"due to their security implications.\";\n            throw new IllegalStateException(msg);\n        }\n        if (this.compressionCodecResolver != null && !Jwts.ZIP.get().equals(this.zipAlgs)) {\n            String msg = \"Both 'zip()' and 'compressionCodecResolver' \" +\n                    \"cannot be configured. Choose either.\";\n            throw new IllegalStateException(msg);\n        }\n\n        // Invariants.  If these are ever violated, it's an error in this class implementation:\n        Assert.stateNotNull(keyLocator, \"Key locator should never be null.\");\n\n        final DefaultClaims expClaims = (DefaultClaims) this.expectedClaims.build();\n\n        return new DefaultJwtParser(\n                provider,\n                signingKeyResolver,\n                unsecured,\n                unsecuredDecompression,\n                keyLocator,\n                clock,\n                critical,\n                allowedClockSkewMillis,\n                expClaims,\n                decoder,","sourceCodeStart":385,"sourceCodeEnd":421,"githubUrl":"https://github.com/jwtk/jjwt/blob/fb71496164c71442d08adec4571d9616ed5e1b8d/impl/src/main/java/io/jsonwebtoken/impl/DefaultJwtParserBuilder.java#L385-L421","documentation":"JwtParser.build() forbids configuring both the zip(...) algorithm set and a custom compressionCodecResolver, since they are two competing ways to decide how compressed JWT payloads are decompressed. The builder throws IllegalStateException to resolve the ambiguity up front rather than during parsing.","triggerScenarios":"Calling JwtParserBuilder.zip(algorithms) and compressionCodecResolver(resolver) on the same builder, then build().","commonSituations":"Adding a custom codec resolver for a non-standard compression algorithm while a zip(...) whitelist from earlier code remains; wrapping legacy builder code where the newer zip() API was layered over an old resolver.","solutions":["Remove compressionCodecResolver(...) and keep zip(...) for standard algorithm selection","Remove zip(...) and keep compressionCodecResolver(...) for fully custom resolution","Audit the builder construction path so only one compression configuration mechanism is used"],"exampleFix":"// before\nJwtParser parser = Jwts.parser()\n    .zip(Jwts.ZIP.DEF)  // plus leftover:\n    .compressionCodecResolver(resolver)\n    .build();\n// after\nJwtParser parser = Jwts.parser()\n    .zip(Jwts.ZIP.DEF)\n    .build();","handlingStrategy":"validation","validationCode":"if (codecResolver != null && zipAlgs != null) {\n    throw new IllegalArgumentException(\"Use either zip() or compressionCodecResolver, not both\");\n}","typeGuard":null,"tryCatchPattern":"try {\n    JwtParser p = builder.build();\n} catch (IllegalStateException e) {\n    log.error(\"Compression config conflict: {}\", e.getMessage());\n}","preventionTips":["Use zip() for standard algorithms and only drop to a custom resolver when truly needed","Strip old resolver configuration when adopting the zip() API","Add a parser-builder unit test asserting build() succeeds"],"tags":["jwt","parser-config","compression","conflicting-options"],"backgroundTag":"conflicting-config-options","analyzedSha":"fb71496164c71442d08adec4571d9616ed5e1b8d","analyzedAt":"2026-09-09T00:33:09.982Z","contentChangedAt":"2026-09-09T00:33:09.982Z","schemaVersion":2},"datasetVersion":"2026-09-14T11:17:12.474Z"}