{"record":{"id":"b1260071417845de","repo":"jwtk/jjwt","slug":"both-a-signingkeyresolver-and-a-verifywith-key","errorCode":null,"errorMessage":"Both a 'signingKeyResolver and a 'verifyWith' key cannot be configured. Choose either, or prefer `keyLocator` when possible.","messagePattern":"Both a 'signingKeyResolver and a 'verifyWith' key cannot be configured\\. Choose either, or prefer `keyLocator` when possible\\.","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"impl/src/main/java/io/jsonwebtoken/impl/DefaultJwtParserBuilder.java","lineNumber":374,"sourceCode":"\n    @SuppressWarnings(\"deprecation\")\n    @Override\n    public JwtParserBuilder setCompressionCodecResolver(CompressionCodecResolver resolver) {\n        this.compressionCodecResolver = Assert.notNull(resolver, \"CompressionCodecResolver cannot be null.\");\n        return this;\n    }\n\n    @Override\n    public JwtParser build() {\n\n        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        }","sourceCodeStart":356,"sourceCodeEnd":392,"githubUrl":"https://github.com/jwtk/jjwt/blob/fb71496164c71442d08adec4571d9616ed5e1b8d/impl/src/main/java/io/jsonwebtoken/impl/DefaultJwtParserBuilder.java#L356-L392","documentation":"Thrown as IllegalStateException from DefaultJwtParserBuilder.build() when both a SigningKeyResolver and an explicit verifyWith key have been configured. These two key sources are mutually exclusive for JWS verification — the builder cannot decide which to use — so building the parser fails fast.","triggerScenarios":"parserBuilder().setSigningKeyResolver(resolver).verifyWith(key)...build(); typically after adding verifyWith to existing resolver-based code, or when shared builder-configuration code sets both.","commonSituations":"Gradual migration from the deprecated signingKeyResolver API to verifyWith leaving both set; framework/interceptor code that configures a resolver conditionally while other code sets a static key; copy-pasted parser configuration accumulating settings.","solutions":["Remove the setSigningKeyResolver(...) call if all tokens are verified with one static key.","Remove verifyWith(...) if the resolver is needed to select keys per-token (e.g. per-kid lookup).","Prefer keyLocator (per the message) for dynamic key selection; ensure resolver/verifyWith are unset when using it.","Guard shared configuration code so exactly one of {keyLocator, signingKeyResolver, signatureVerificationKey} is set — assert before build()."],"exampleFix":"// before\nJwts.parser()\n    .setSigningKeyResolver(resolver)\n    .verifyWith(publicKey) // conflicts\n    .build();\n// after\nJwts.parser().verifyWith(publicKey).build();\n// or for per-token key choice:\nJwts.parser().keyLocator(locate -> byKid(locate.getHeader().get(\"kid\", String.class))).build();","handlingStrategy":"validation","validationCode":"// before build(): ensure exactly one JWS key source is configured\nint sources = (resolver != null ? 1 : 0) + (verifyKey != null ? 1 : 0) + (keyLocator != null ? 1 : 0);\nif (sources > 1) throw new IllegalStateException(\"Configure only one of signingKeyResolver/verifyWith/keyLocator\");","typeGuard":null,"tryCatchPattern":"try {\n    JwtParser parser = Jwts.parser().verifyWith(key).build();\n} catch (IllegalStateException e) {\n    // conflicting key configuration; strip resolver or verifyWith\n}","preventionTips":["Configure exactly one JWS key source per parser: keyLocator, signingKeyResolver, OR verifyWith","When migrating from signingKeyResolver to verifyWith, delete the old call completely","Centralize parser construction in one factory method to avoid accumulating settings","Prefer keyLocator for dynamic (per-kid) key selection in new code"],"tags":["jwt","configuration","mutually-exclusive-options","parser-builder"],"backgroundTag":"mutually-exclusive-options","analyzedSha":"fb71496164c71442d08adec4571d9616ed5e1b8d","analyzedAt":"2026-09-09T00:33:09.982Z","contentChangedAt":"2026-09-09T00:33:09.982Z","schemaVersion":2},"datasetVersion":"2026-09-17T15:17:12.973Z"}