{"record":{"id":"9efc19e6bef36a34","repo":"jwtk/jjwt","slug":"both-keylocator-and-a-verifywith-key-cannot-be","errorCode":null,"errorMessage":"Both 'keyLocator' and a 'verifyWith' key cannot be configured. Prefer 'keyLocator' if possible.","messagePattern":"Both 'keyLocator' and a 'verifyWith' key cannot be configured\\. Prefer 'keyLocator' if possible\\.","errorType":"exception","errorClass":"java.lang.IllegalStateException","httpStatus":null,"severity":"error","filePath":"impl/src/main/java/io/jsonwebtoken/impl/DefaultJwtParserBuilder.java","lineNumber":385,"sourceCode":"        if (this.deserializer == null) {\n            //noinspection unchecked\n            json(Services.get(Deserializer.class));\n        }\n        if (this.signingKeyResolver != null && this.signatureVerificationKey != null) {\n            String msg = \"Both a 'signingKeyResolver and a 'verifyWith' key cannot be configured. \" +\n                    \"Choose either, or prefer `keyLocator` when possible.\";\n            throw new IllegalStateException(msg);\n        }\n        if (this.keyLocator != null) {\n            if (this.signatureVerificationKey != null) {\n                String msg = \"Both 'keyLocator' and a 'verifyWith' key cannot be configured. \" +\n                        \"Prefer 'keyLocator' if possible.\";\n                throw new IllegalStateException(msg);\n            }\n            if (this.decryptionKey != null) {\n                String msg = \"Both 'keyLocator' and a 'decryptWith' key cannot be configured. \" +\n                        \"Prefer 'keyLocator' if possible.\";\n                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);","sourceCodeStart":367,"sourceCodeEnd":403,"githubUrl":"https://github.com/jwtk/jjwt/blob/fb71496164c71442d08adec4571d9616ed5e1b8d/impl/src/main/java/io/jsonwebtoken/impl/DefaultJwtParserBuilder.java#L367-L403","documentation":"JwtParser.build() rejects configuring both a keyLocator (dynamic key lookup strategy) and an explicit verifyWith key. These are two alternative mechanisms for obtaining the verification key, so having both is ambiguous and the builder fails fast with IllegalStateException. The message advises preferring keyLocator when possible.","triggerScenarios":"Calling JwtParserBuilder.keyLocator(locator) together with verifyWith(key) on the same builder instance, then calling build().","commonSituations":"Incrementally adopting the keyLocator API while an older verifyWith call remains; framework code that injects a locator and application code that also sets a static key; reusing a parser builder across environments where one path sets each.","solutions":["Remove verifyWith(key) and rely solely on keyLocator","Remove keyLocator(...) if a fixed verification key is sufficient and keep verifyWith(key)","Audit builder call sites so only one key-source mechanism is applied"],"exampleFix":"// before\nJwtParser parser = Jwts.parser()\n    .keyLocator(locator)\n    .verifyWith(publicKey)\n    .build();\n// after\nJwtParser parser = Jwts.parser()\n    .keyLocator(locator)\n    .build();","handlingStrategy":"validation","validationCode":"if (keyLocator != null && verificationKey != null) {\n    throw new IllegalArgumentException(\"Use either keyLocator or verifyWith, not both\");\n}","typeGuard":null,"tryCatchPattern":"try {\n    JwtParser p = Jwts.parser().keyLocator(locator).build();\n} catch (IllegalStateException e) {\n    log.error(\"Parser key config conflict: {}\", e.getMessage());\n}","preventionTips":["Choose keyLocator as the single key mechanism when keys rotate","Remove legacy verifyWith calls when introducing keyLocator","Unit-test parser construction in CI to catch config regressions"],"tags":["jwt","parser-config","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-14T05:17:10.506Z"}