{"record":{"id":"14a3e2fef0cdd5fb","repo":"quarkusio/quarkus","slug":"setter-settername-of-class-configcl","errorCode":null,"errorMessage":"Setter '' + setterName + '' of class '' + configClassInfo + '' must be public","messagePattern":"Setter '' \\+ setterName \\+ '' of class '' \\+ configClassInfo \\+ '' must be public","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"extensions/spring-boot-properties/deployment/src/main/java/io/quarkus/spring/boot/properties/deployment/ClassConfigurationPropertiesUtil.java","lineNumber":298,"sourceCode":"                String setterName = JavaBeanUtil.getSetterName(field.name());\n                Type fieldType = field.type();\n                MethodInfo setter = currentClassInHierarchy.method(setterName, fieldType);\n                if (setter == null) {\n                    if (!Modifier.isPublic(field.flags()) || Modifier.isFinal(field.flags())) {\n                        String message = \"Configuration properties class '\" + configClassInfo\n                                + \"' does not have a setter for field '\"\n                                + field.name() + \"' nor is the field a public non-final field.\";\n                        if (failOnMismatchingMember) {\n                            throw new IllegalArgumentException(message);\n                        } else {\n                            LOGGER.warn(message + \" It will therefore be ignored.\");\n                            continue;\n                        }\n                    }\n                    useFieldAccess = true;\n                }\n                if (!useFieldAccess && !Modifier.isPublic(setter.flags())) {\n                    throw new IllegalArgumentException(\n                            \"Setter '\" + setterName + \"' of class '\" + configClassInfo + \"' must be public\");\n                }\n\n                /*\n                 * If the object is part of the application we are dealing with a nested object\n                 * What we do is simply recursively build it up based by adding the field name to the config name prefix\n                 */\n                DotName fieldTypeDotName = fieldType.name();\n                ClassInfo fieldTypeClassInfo = applicationIndex.getClassByName(fieldType.name());\n                if (fieldTypeClassInfo != null) {\n                    if (DotNames.ENUM.equals(fieldTypeClassInfo.superName())) {\n                        populateTypicalProperty(bc, configObject, configPropertyBuildItemCandidates,\n                                currentClassInHierarchy, field, useFieldAccess, fieldType, setter, configParam,\n                                getFullConfigName(prefixStr, namingStrategy, field));\n\n                        // we need to register the 'valueOf' method of the enum for reflection because\n                        // that is the method that SmallryeConfig uses for conversion of enums\n                        List<MethodInfo> methods = fieldTypeClassInfo.methods();","sourceCodeStart":280,"sourceCodeEnd":316,"githubUrl":"https://github.com/quarkusio/quarkus/blob/e1c734241f34c7919086ceb4c9262b4a58f6de44/extensions/spring-boot-properties/deployment/src/main/java/io/quarkus/spring/boot/properties/deployment/ClassConfigurationPropertiesUtil.java#L280-L316","documentation":"When a setter method exists for a configuration field but is not public, the framework cannot invoke it reflectively at build time to populate the config object. Non-public setters are therefore rejected with this IllegalArgumentException.","triggerScenarios":"populateConfigObject resolves the setter for a field and, when useFieldAccess is false, checks Modifier.isPublic(setter.flags()); a protected/package-private/private setter triggers the throw.","commonSituations":"Fluent setters returning 'this' made package-private; setters narrowed to protected for subclass-only access during refactoring; generated classes with restricted accessors.","solutions":["Make the setter method public.","Alternatively make the field public non-final so field access is used instead of the setter.","Rename the accessor if it is not actually intended as the bound setter."],"exampleFix":"// before\nvoid setName(String name) { this.name = name; }\n// after\npublic void setName(String name) { this.name = name; }","handlingStrategy":"validation","validationCode":"static void checkPublicSetters(Class<?> props) {\n    for (Method m : props.getDeclaredMethods()) {\n        if (m.getName().startsWith(\"set\") && m.getParameterCount() == 1\n                && !Modifier.isPublic(m.getModifiers()))\n            throw new IllegalArgumentException(m + \" must be public\");\n    }\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Keep all config setters public.","Avoid fluent setters returning 'this' with reduced visibility in properties classes.","Re-check access modifiers after refactoring accessor visibility."],"tags":["quarkus","spring-boot","configuration-properties","visibility"],"backgroundTag":"non-public-setter","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"}