{"record":{"id":"7da72cb12810822f","repo":"quarkusio/quarkus","slug":"tls-client-authentication-has-already-been-enabled","errorCode":null,"errorMessage":"TLS client authentication has already been enabled with this API or with the 'quarkus.http.ssl.client-auth' configuration property","messagePattern":"TLS client authentication has already been enabled with this API or with the 'quarkus\\.http\\.ssl\\.client-auth' configuration property","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"extensions/vertx-http/runtime/src/main/java/io/quarkus/vertx/http/runtime/security/HttpSecurityImpl.java","lineNumber":139,"sourceCode":"            final FormAuthConfig actualConfig = vertxHttpConfig.auth().form();\n            if (!actualConfig.equals(defaults)) {\n                throw new IllegalArgumentException(\"Cannot configure form-based authentication programmatically \"\n                        + \"because it has already been configured in the 'application.properties' file\");\n            }\n        } else if (mechanism.getClass() == BasicAuthenticationMechanism.class) {\n            String actualRealm = vertxHttpConfig.auth().realm().orElse(null);\n            if (actualRealm != null) {\n                throw new IllegalArgumentException(\"Cannot configure basic authentication programmatically because \"\n                        + \"the authentication realm has already been configured in the 'application.properties' file\");\n            }\n        } else if (mechanism.getClass() == MtlsAuthenticationMechanism.class) {\n            boolean mTlsEnabled = !ClientAuth.NONE.equals(clientAuth);\n            if (mTlsEnabled) {\n                // current we do not allow \"merging\" (or overriding) of the configuration provided in application.properties\n                // there shouldn't be a technical issue allowing that, but that's the behavior we have for other mechanisms\n                // as well, so this method only allows to \"enable\" mTLS, never disable or change configuration provided\n                // properties file\n                throw new IllegalArgumentException(\"TLS client authentication has already been enabled with this API or\"\n                        + \" with the 'quarkus.http.ssl.client-auth' configuration property\");\n            }\n            var mTLS = ((MtlsAuthenticationMechanism) mechanism);\n            clientAuth = mTLS.getTlsClientAuth();\n            if (mTLS.getHttpServerTlsConfigName().isPresent()) {\n                if (httpServerTlsConfigName.isPresent()) {\n                    throw new IllegalArgumentException(\"Cannot configure TLS configuration name programmatically because it \"\n                            + \" has already been configured with the 'quarkus.http.tls-configuration-name' configuration property\");\n                }\n                httpServerTlsConfigName = mTLS.getHttpServerTlsConfigName();\n                if (mTLS.getInitialTlsConfiguration() != null) {\n                    TlsConfigurationRegistry tlsConfigurationRegistry = Arc.container().instance(TlsConfigurationRegistry.class)\n                            .get();\n                    if (tlsConfigurationRegistry.get(httpServerTlsConfigName.get()).isPresent()) {\n                        throw new IllegalArgumentException((\"Cannot register the TLS configuration '%s' in the TLS \"\n                                + \"Configuration registry because configuration with this name has already\"\n                                + \" been registered\").formatted(httpServerTlsConfigName.get()));\n                    }","sourceCodeStart":121,"sourceCodeEnd":157,"githubUrl":"https://github.com/quarkusio/quarkus/blob/e1c734241f34c7919086ceb4c9262b4a58f6de44/extensions/vertx-http/runtime/src/main/java/io/quarkus/vertx/http/runtime/security/HttpSecurityImpl.java#L121-L157","documentation":"When an MtlsAuthenticationMechanism is registered via mechanism(), Quarkus checks whether TLS client authentication (clientAuth) is already enabled either by a previous programmatic mTLS call or by the quarkus.http.ssl.client-auth property. Since merging/overriding mTLS configuration is not supported, a second enabling attempt throws an IllegalArgumentException.","triggerScenarios":"Calling httpSecurity.mTLS(...) or mechanism(new MtlsAuthenticationMechanism(...)) more than once, or calling it after quarkus.http.ssl.client-auth is set to REQUIRED/REQUEST in application.properties.","commonSituations":"Migrating mTLS from properties-based config to the programmatic API while the property remains set; duplicate registration of the same mechanism in a security setup helper that is invoked twice.","solutions":["Remove quarkus.http.ssl.client-auth from application.properties and configure mTLS only programmatically.","Register the mTLS mechanism exactly once; search the codebase for duplicated mTLS()/mechanism() calls.","Keep mTLS solely in application.properties and delete the programmatic registration."],"exampleFix":"// before (application.properties)\nquarkus.http.ssl.client-auth=REQUIRED\n// code: httpSecurity.mTLS(ClientAuth.REQUIRED) // throws\n// after: remove the property, then configure once in code\nhttpSecurity.mTLS(ClientAuth.REQUIRED);","handlingStrategy":"validation","validationCode":"// ensure quarkus.http.ssl.client-auth is unset before programmatic mTLS\n// ConfigProvider.getConfig().getOptionalValue(\"quarkus.http.ssl.client-auth\", String.class)\n//     .ifPresent(v -> { throw new IllegalStateException(\"ssl.client-auth already set in properties\"); });\nhttpSecurity.mTLS(ClientAuth.REQUIRED); // call exactly once","typeGuard":null,"tryCatchPattern":"try {\n    httpSecurity.mTLS(ClientAuth.REQUIRED);\n} catch (IllegalArgumentException e) {\n    if (e.getMessage().contains(\"TLS client authentication has already been enabled\")) {\n        log.warn(\"mTLS already enabled via properties or a prior call; skipping\");\n    } else {\n        throw e;\n    }\n}","preventionTips":["Register the mTLS mechanism exactly once — centralize it in a single setup method.","Remove quarkus.http.ssl.client-auth when enabling mTLS programmatically.","Guard idempotency if setup code can run more than once (dev-mode restarts, multiple initializers)."],"tags":["quarkus","http-security","mtls","tls","duplicate-configuration"],"backgroundTag":"duplicate-configuration-source","analyzedSha":"e1c734241f34c7919086ceb4c9262b4a58f6de44","analyzedAt":"2026-09-05T17:01:29.979Z","contentChangedAt":"2026-09-05T17:01:29.979Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}