quarkusio/quarkus · error · IllegalStateException

Default SecurityCheck has already been registered

Error message

Default SecurityCheck has already been registered

What it means

Thrown by SecurityCheckStorageBuilder.registerDefaultSecurityCheck when more than one default SecurityCheck is registered while building the security interceptor storage. Quarkus registers the default check (e.g. DenyAllAuthenticationCheck) once during build; a second registration is a programming/extension error, not a user configuration error.

Source

Thrown at extensions/security/runtime/src/main/java/io/quarkus/security/runtime/interceptor/SecurityCheckStorageBuilder.java:23

import io.quarkus.security.spi.runtime.MethodDescription;
import io.quarkus.security.spi.runtime.SecurityCheck;
import io.quarkus.security.spi.runtime.SecurityCheckStorage;

public class SecurityCheckStorageBuilder {
    private final Map<MethodDescription, SecurityCheck> securityChecks = new HashMap<>();
    private SecurityCheck defaultSecurityCheck;

    public void registerCheck(String className,
            String methodName,
            String[] parameterTypes,
            SecurityCheck securityCheck) {
        securityChecks.put(new MethodDescription(className, methodName, parameterTypes), securityCheck);
    }

    public void registerDefaultSecurityCheck(SecurityCheck defaultSecurityCheck) {
        if (this.defaultSecurityCheck != null) {
            throw new IllegalStateException("Default SecurityCheck has already been registered");
        }
        this.defaultSecurityCheck = defaultSecurityCheck;
    }

    public SecurityCheckStorage create() {
        return new SecurityCheckStorage() {
            @Override
            public SecurityCheck getSecurityCheck(MethodDescription methodDescription) {
                return securityChecks.get(methodDescription);
            }

            @Override
            public SecurityCheck getDefaultSecurityCheck() {
                return defaultSecurityCheck;
            }
        };
    }
}

View on GitHub (pinned to e1c734241f)

Solutions

  1. Remove your custom registerDefaultSecurityCheck call and rely on Quarkus's built-in default (deny-all for unannotated methods)
  2. If a custom default is required, register it exactly once and guard/skip when another is already present
  3. Check for duplicate @BuildStep methods or recorders registering the default check twice

Example fix

// before
builder.registerDefaultSecurityCheck(new DenyAllCheck());
builder.registerDefaultSecurityCheck(new PermitAllCheck()); // IllegalStateException
// after
builder.registerDefaultSecurityCheck(new DenyAllCheck()); // single default only
Defensive patterns

Strategy: validation

Validate before calling

// extension author guard
if (builderDefaultCheckAlreadySet) {
  // skip registering your own default security check
}

Try / catch

try {
  builder.registerDefaultSecurityCheck(check);
} catch (IllegalStateException e) {
  // another default was already registered; keep the existing one
  log.warn("Default SecurityCheck already registered, skipping");
}

Prevention

When it happens

Trigger: Calling registerDefaultSecurityCheck twice on the same SecurityCheckStorageBuilder instance — typically from a custom extension build step that registers a default check in addition to Quarkus's own default registration.

Common situations: Custom security extension adding its own default check (e.g. Jakarta annotations @PermitAll default) without accounting for quarkus-vertx-http/security already registering DenyAllAuthenticationCheck; duplicated recorder invocations during incremental builds.

Related errors


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