{"record":{"id":"37bb25449ef491d0","repo":"quarkusio/quarkus","slug":"cannot-configure-form-based-authentication-program","errorCode":null,"errorMessage":"Cannot configure form-based authentication programmatically because it has already been configured in the 'application.properties' file","messagePattern":"Cannot configure form-based authentication programmatically because it has already been configured in the 'application\\.properties' file","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":123,"sourceCode":"    }\n\n    @Override\n    public HttpSecurity csrf(CSRF csrf) {\n        if (csrf == null) {\n            throw new IllegalArgumentException(\"CSRF must not be null\");\n        }\n        this.csrf = csrf;\n        return this;\n    }\n\n    @Override\n    public HttpSecurity mechanism(HttpAuthenticationMechanism mechanism) {\n        Objects.requireNonNull(mechanism);\n        if (mechanism.getClass() == FormAuthenticationMechanism.class) {\n            final FormAuthConfig defaults = HttpSecurityUtils.getDefaultAuthConfig().auth().form();\n            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            }","sourceCodeStart":105,"sourceCodeEnd":141,"githubUrl":"https://github.com/quarkusio/quarkus/blob/e1c734241f34c7919086ceb4c9262b4a58f6de44/extensions/vertx-http/runtime/src/main/java/io/quarkus/vertx/http/runtime/security/HttpSecurityImpl.java#L105-L141","documentation":"When a FormAuthenticationMechanism is registered programmatically via HttpSecurity.mechanism(), Quarkus compares the form auth config in application.properties against the defaults. If any quarkus.http.auth.form.* property was customized, the configuration is considered already owned by the properties file and merging/overriding programmatically is disallowed, so an IllegalArgumentException is thrown. This keeps a single source of truth for form-based auth configuration.","triggerScenarios":"Calling httpSecurity.mechanism(new FormAuthenticationMechanism(...)) (or any API that routes through mechanism()) while application.properties contains non-default quarkus.http.auth.form.* settings (e.g. quarkus.http.auth.form.enabled, landing-page, post-location, cookie parameters).","commonSituations":"Applications that originally configured form auth via application.properties and later add programmatic security setup; copied config files that still carry form properties; following docs examples that register form auth in code while an old properties entry remains.","solutions":["Remove or reset all quarkus.http.auth.form.* properties from application.properties so the programmatic config is the sole source.","Configure form authentication exclusively in application.properties and drop the programmatic mechanism() call.","If both are needed, move the properties values into the programmatic FormAuthenticationMechanism configuration instead."],"exampleFix":"// before (application.properties)\nquarkus.http.auth.form.landing-page=/index.html\n// code: httpSecurity.mechanism(new FormAuthenticationMechanism(...)) // throws\n// after: remove the landing-page property, or drop the programmatic registration\nhttpSecurity.mechanism(new FormAuthenticationMechanism(...));","handlingStrategy":"validation","validationCode":"// before registering form auth programmatically, ensure no form properties are set\n// ConfigProvider.getConfig().getOptionalValue(\"quarkus.http.auth.form.enabled\", Boolean.class)\n//     .ifPresent(v -> { throw new IllegalStateException(\"Form auth already configured via properties\"); });\nhttpSecurity.mechanism(new FormAuthenticationMechanism(...));","typeGuard":null,"tryCatchPattern":"try {\n    httpSecurity.mechanism(formMechanism);\n} catch (IllegalArgumentException e) {\n    if (e.getMessage().contains(\"form-based authentication\")) {\n        log.warn(\"Form auth already configured in application.properties; skipping programmatic registration\");\n    } else {\n        throw e;\n    }\n}","preventionTips":["Pick one source of truth (properties OR code) for form authentication per application.","Grep application.properties for quarkus.http.auth.form.* before adding programmatic form auth.","Inherited/shared property files often carry stale form settings — audit them during migration."],"tags":["quarkus","http-security","form-auth","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-12T22:17:10.623Z"}