quarkusio/quarkus · error · IllegalArgumentException

Authorization has already been set

Error message

Authorization has already been set

What it means

Thrown by validateAuthorizationNotSetYet when authorization() is called on a HttpPermission whose authorizationPolicy is already set while no authentication mechanism (authMechanism) has been configured. The authorization() method pairs a custom policy with an implicit authentication requirement, so a pre-existing policy makes the call invalid.

Source

Thrown at extensions/vertx-http/runtime/src/main/java/io/quarkus/vertx/http/runtime/security/HttpSecurityImpl.java:404

        private void requireAuthenticationByDefault() {
            // if someone selects authentication mechanism and doesn't configure
            // authorization policy, it is reasonable to expect they require authentication
            // similarly to what we do with @BasicAuthentication etc.
            if (authorizationPolicy == null) {
                authenticated();
            }
        }

        private void validateAuthenticationNotSetYet() {
            if (authMechanism != null) {
                throw new IllegalArgumentException("Authentication has already been set");
            }
        }

        private void validateAuthorizationNotSetYet() {
            if (authMechanism == null && authorizationPolicy != null) {
                throw new IllegalArgumentException("Authorization has already been set");
            }
        }

        @Override
        public HttpPermission basic() {
            return authenticatedWith(BasicAuthentication.AUTH_MECHANISM_SCHEME);
        }

        @Override
        public HttpPermission form() {
            return authenticatedWith(FormAuthentication.AUTH_MECHANISM_SCHEME);
        }

        @Override
        public HttpPermission mTLS() {
            boolean mTlsDisabled = ClientAuth.NONE.equals(clientAuth);
            if (mTlsDisabled) {
                throw new IllegalStateException(

View on GitHub (pinned to e1c734241f)

Solutions

  1. Call authorization(...) only once per HttpPermission, before any roles()/permissions() call.
  2. Remove the earlier roles()/permissions() call if the custom policy in authorization() should govern.
  3. Use a fresh permission from paths() for the custom authorization policy.

Example fix

// before
var perm = httpSecurity.paths("/api/*").roles("admin");
perm.authorization(myPolicy); // throws
// after
httpSecurity.paths("/api/*").authorization(myPolicy);
Defensive patterns

Strategy: validation

Validate before calling

if (permUsesRolesOrPermissions) { /* do not call authorization(...) on the same permission */ }

Try / catch

try { perm.authorization(policy); } catch (IllegalArgumentException e) { if (!e.getMessage().contains("Authorization has already been set")) throw e; }

Prevention

When it happens

Trigger: Calling .roles(...) or .permissions(...) (which set authorizationPolicy) followed by .authorization(policy) on the same HttpPermission, without an intermediate authenticated()/authenticatedWith(...) call.

Common situations: Migrating from roles()/permissions() style config to a custom HttpSecurityPolicy with authorization() on the same builder; helper methods that each set an authorization policy on a shared permission.

Related errors


AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05). Data as JSON: /api/errors/ec811f4d206e3e41. Report an issue: GitHub.