{"record":{"id":"3b16523622df008e","repo":"quarkusio/quarkus","slug":"configuration-properties-class-configclassinf","errorCode":null,"errorMessage":"Configuration properties class '' + configClassInfo + '' does not have a setter for field ' + field.name() + ' nor is the field a public non-final field.","messagePattern":"Configuration properties class '' \\+ configClassInfo \\+ '' does not have a setter for field ' \\+ field\\.name\\(\\) \\+ ' nor is the field a public non-final field\\.","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":289,"sourceCode":"                    if ((configPropertyDefaultValue != null)\n                            && !configPropertyDefaultValue.asString().equals(ConfigProperty.UNCONFIGURED_VALUE)) {\n                        LOGGER.warn(\n                                \"'defaultValue' of '@ConfigProperty' is ignored when added to a field of a class annotated with '@ConfigProperties'. Offending field is '\"\n                                        + field.name() + \"' of class '\" + field.declaringClass().toString() + \"'\");\n                    }\n                }\n                boolean useFieldAccess = false;\n\n                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());","sourceCodeStart":271,"sourceCodeEnd":307,"githubUrl":"https://github.com/quarkusio/quarkus/blob/e1c734241f34c7919086ceb4c9262b4a58f6de44/extensions/spring-boot-properties/deployment/src/main/java/io/quarkus/spring/boot/properties/deployment/ClassConfigurationPropertiesUtil.java#L271-L307","documentation":"Every property field of a Spring-style @ConfigurationProperties class must be bindable: either via a setter or via a public non-final field. When neither exists, the build fails if failOnMismatchingMember is true; otherwise the member is skipped with a warning.","triggerScenarios":"populateConfigObject iterates each field of the config class; when no setter method is found and the field is private, or public but final, it throws IllegalArgumentException (strict mode) or logs a warning and skips the field.","commonSituations":"Spring Boot classes relying on constructor binding (no setters, final fields) migrated to Quarkus; fields renamed without updating accessors; immutable value-style config classes.","solutions":["Add a public setter (setFieldName) for each bound field.","Or make the field public and non-final so field access is used.","Set quarkus.spring-config-properties.fail-on-mismatching-member=false only if you accept the field being ignored with a warning."],"exampleFix":"// before\n@ConfigurationProperties(\"app\")\npublic class AppProps {\n    public final String name = \"x\"; // public final: rejected\n}\n// after\n@ConfigurationProperties(\"app\")\npublic class AppProps {\n    private String name;\n    public void setName(String name) { this.name = name; }\n}","handlingStrategy":"validation","validationCode":"static void checkBindable(Class<?> props) {\n    for (Field f : props.getDeclaredFields()) {\n        if (Modifier.isStatic(f.getModifiers())) continue;\n        boolean hasSetter = Arrays.stream(props.getMethods())\n                .anyMatch(m -> m.getName().equals(\"set\" + capitalize(f.getName()))\n                        && m.getParameterCount() == 1);\n        boolean publicNonFinal = Modifier.isPublic(f.getModifiers()) && !Modifier.isFinal(f.getModifiers());\n        if (!hasSetter && !publicNonFinal)\n            throw new IllegalArgumentException(\"Field \" + f.getName() + \" in \" + props + \" is not bindable\");\n    }\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Give every bound field a public setter or make it public non-final.","Avoid final fields in Spring-style properties classes on Quarkus.","Only disable fail-on-mismatching-member if silently ignoring the field is acceptable."],"tags":["quarkus","spring-boot","configuration-properties","binding"],"backgroundTag":"missing-config-setter","analyzedSha":"e1c734241f34c7919086ceb4c9262b4a58f6de44","analyzedAt":"2026-09-05T17:01:29.979Z","contentChangedAt":"2026-09-05T17:01:29.979Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}