{"record":{"id":"e65fb840bd899585","repo":"quarkusio/quarkus","slug":"the-certificate-to-roles-mapper-is-already-configu-e65fb8","errorCode":null,"errorMessage":"The certificate to roles mapper is already configured with the 'rolesMapping' method","messagePattern":"The certificate to roles mapper is already configured with the 'rolesMapping' method","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"extensions/vertx-http/runtime/src/main/java/io/quarkus/vertx/http/security/MTLS.java","lineNumber":272,"sourceCode":"            return this;\n        }\n\n        private void assertCertificateToRolesMapperNotSetYet() {\n            if (certificateToRolesMapper != null) {\n                throw new IllegalStateException(\n                        \"The certificate to roles mapper is already configured with the 'certificateToRolesMapper' method\");\n            }\n        }\n\n        /**\n         * Check the values of different client certificate attributes and map them to the {@link SecurityIdentity} roles.\n         *\n         * @param certificateToRolesMapper a client certificate to the {@link SecurityIdentity} roles mapper\n         * @return Builder\n         */\n        public Builder certificateToRolesMapper(Function<X509Certificate, Set<String>> certificateToRolesMapper) {\n            if (certificateAttributeValueToRoles != null) {\n                throw new IllegalStateException(\n                        \"The certificate to roles mapper is already configured with the 'rolesMapping' method\");\n            }\n            assertCertificateToRolesMapperNotSetYet();\n            this.certificateToRolesMapper = certificateToRolesMapper;\n            return this;\n        }\n\n        /**\n         * Mutual TLS authentication mechanism priority.\n         *\n         * @param priority {@link MtlsAuthenticationMechanism#getPriority()}\n         * @return Builder\n         * @see AuthRuntimeConfig#mTlsPriority()\n         */\n        public Builder priority(int priority) {\n            this.priority = Optional.of(priority);\n            return this;\n        }","sourceCodeStart":254,"sourceCodeEnd":290,"githubUrl":"https://github.com/quarkusio/quarkus/blob/e1c734241f34c7919086ceb4c9262b4a58f6de44/extensions/vertx-http/runtime/src/main/java/io/quarkus/vertx/http/security/MTLS.java#L254-L290","documentation":"The inverse guard of MTLS.Builder: certificateToRolesMapper(Function) throws IllegalStateException when rolesMapping-based mapping (certificateAttributeValueToRoles) was already configured. The builder allows only one certificate-to-roles mapping mechanism at a time.","triggerScenarios":"Calling MTLS.Builder.certificateToRolesMapper(...) after certificateAttribute(...) or rolesMapping(...) has already populated certificateAttributeValueToRoles on the same builder.","commonSituations":"Composing mTLS configuration from multiple sources (application config plus code) where attribute mapping is set up first and a custom mapper is then added; refactored security setup that chained both methods.","solutions":["Remove the certificateToRolesMapper(...) call and keep attribute-based mapping","Or remove rolesMapping()/certificateAttribute() and use only the custom mapper function","Encode attribute rules inside the single certificateToRolesMapper function if both are required"],"exampleFix":"// before\nmtls.rolesMapping(Map.of(\"CN=acme\", Set.of(\"user\")))\n    .certificateToRolesMapper(cert -> Set.of(\"admin\")); // IllegalStateException\n// after\nmtls.rolesMapping(Map.of(\"CN=acme\", Set.of(\"user\")));","handlingStrategy":"validation","validationCode":"if (attributeMappingConfigured) { /* do not call certificateToRolesMapper */ }","typeGuard":null,"tryCatchPattern":"try { mtls.certificateToRolesMapper(fn); } catch (IllegalStateException e) { log.warn(\"rolesMapping already configured; ignoring custom mapper\"); }","preventionTips":["Decide once between attribute-based mapping and a custom mapper function","Keep MTLS.Builder construction in one code path, not spread across config and code","Document which mechanism your application uses"],"tags":["mtls","security","illegal-state","builder-misuse"],"backgroundTag":"builder-conflicting-configuration","analyzedSha":"e1c734241f34c7919086ceb4c9262b4a58f6de44","analyzedAt":"2026-09-05T17:01:29.979Z","contentChangedAt":"2026-09-05T17:01:29.979Z","schemaVersion":2},"datasetVersion":"2026-09-12T22:17:10.623Z"}