{"record":{"id":"e61df56eef8e9504","repo":"quarkusio/quarkus","slug":"default-securitycheck-has-already-been-registered","errorCode":null,"errorMessage":"Default SecurityCheck has already been registered","messagePattern":"Default SecurityCheck has already been registered","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"extensions/security/runtime/src/main/java/io/quarkus/security/runtime/interceptor/SecurityCheckStorageBuilder.java","lineNumber":23,"sourceCode":"\nimport io.quarkus.security.spi.runtime.MethodDescription;\nimport io.quarkus.security.spi.runtime.SecurityCheck;\nimport io.quarkus.security.spi.runtime.SecurityCheckStorage;\n\npublic class SecurityCheckStorageBuilder {\n    private final Map<MethodDescription, SecurityCheck> securityChecks = new HashMap<>();\n    private SecurityCheck defaultSecurityCheck;\n\n    public void registerCheck(String className,\n            String methodName,\n            String[] parameterTypes,\n            SecurityCheck securityCheck) {\n        securityChecks.put(new MethodDescription(className, methodName, parameterTypes), securityCheck);\n    }\n\n    public void registerDefaultSecurityCheck(SecurityCheck defaultSecurityCheck) {\n        if (this.defaultSecurityCheck != null) {\n            throw new IllegalStateException(\"Default SecurityCheck has already been registered\");\n        }\n        this.defaultSecurityCheck = defaultSecurityCheck;\n    }\n\n    public SecurityCheckStorage create() {\n        return new SecurityCheckStorage() {\n            @Override\n            public SecurityCheck getSecurityCheck(MethodDescription methodDescription) {\n                return securityChecks.get(methodDescription);\n            }\n\n            @Override\n            public SecurityCheck getDefaultSecurityCheck() {\n                return defaultSecurityCheck;\n            }\n        };\n    }\n}","sourceCodeStart":5,"sourceCodeEnd":41,"githubUrl":"https://github.com/quarkusio/quarkus/blob/e1c734241f34c7919086ceb4c9262b4a58f6de44/extensions/security/runtime/src/main/java/io/quarkus/security/runtime/interceptor/SecurityCheckStorageBuilder.java#L5-L41","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Remove your custom registerDefaultSecurityCheck call and rely on Quarkus's built-in default (deny-all for unannotated methods)","If a custom default is required, register it exactly once and guard/skip when another is already present","Check for duplicate @BuildStep methods or recorders registering the default check twice"],"exampleFix":"// before\nbuilder.registerDefaultSecurityCheck(new DenyAllCheck());\nbuilder.registerDefaultSecurityCheck(new PermitAllCheck()); // IllegalStateException\n// after\nbuilder.registerDefaultSecurityCheck(new DenyAllCheck()); // single default only","handlingStrategy":"validation","validationCode":"// extension author guard\nif (builderDefaultCheckAlreadySet) {\n  // skip registering your own default security check\n}","typeGuard":null,"tryCatchPattern":"try {\n  builder.registerDefaultSecurityCheck(check);\n} catch (IllegalStateException e) {\n  // another default was already registered; keep the existing one\n  log.warn(\"Default SecurityCheck already registered, skipping\");\n}","preventionTips":["Never call registerDefaultSecurityCheck in custom extensions; rely on the built-in default","Audit @BuildStep methods for duplicate recorder invocations","Guard your recorder with a build-time flag so it runs once"],"tags":["security","interceptor","default-check","build-time"],"backgroundTag":"duplicate-security-check-registration","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"}