quarkusio/quarkus · error · IllegalArgumentException
Nested configuration class ' + fieldTypeClassInfo + ' must b
Error message
Nested configuration class ' + fieldTypeClassInfo + ' must be public
What it means
A field of the configuration properties class is itself a nested configuration object. Nested classes must be instantiable reflectively, and Quarkus requires them to be public; a non-public nested configuration type fails the build.
Source
Thrown at extensions/spring-boot-properties/deployment/src/main/java/io/quarkus/spring/boot/properties/deployment/ClassConfigurationPropertiesUtil.java:331
// we need to register the 'valueOf' method of the enum for reflection because
// that is the method that SmallryeConfig uses for conversion of enums
List<MethodInfo> methods = fieldTypeClassInfo.methods();
for (MethodInfo method : methods) {
if (!method.name().equals("valueOf")) {
continue;
}
if (method.parametersCount() != 1) {
continue;
}
if (method.parameterType(0).name().equals(DotNames.STRING)) {
reflectiveMethods.produce(new ReflectiveMethodBuildItem(getClass().getName(), method));
break;
}
}
} else if (fieldTypeClassInfo.hasNoArgsConstructor()) {
if (!Modifier.isPublic(fieldTypeClassInfo.flags())) {
throw new IllegalArgumentException(
"Nested configuration class '" + fieldTypeClassInfo + "' must be public ");
}
Expr nestedConfigObject = populateConfigObject(classLoader, fieldTypeClassInfo,
getFullConfigName(prefixStr, namingStrategy, field), namingStrategy, failOnMismatchingMember,
null, bc, configParam);
createWriteValue(bc, configObject, field, setter, useFieldAccess, nestedConfigObject);
} else {
LOGGER.warn("Nested configuration class '" + fieldTypeClassInfo
+ "' declared in '" + currentClassInHierarchy.name() + "." + field.name() + "' is either an "
+ "interface or does not have a non-args constructor, so this field will not be initialized");
}
} else {
String fullConfigName = getFullConfigName(prefixStr, namingStrategy, field);
if (DotNames.OPTIONAL.equals(fieldTypeDotName)) {
Type genericType = ConfigurationPropertiesUtil.determineSingleGenericType(field.type(),
field.declaringClass().name());
View on GitHub (pinned to e1c734241f)
Solutions
- Make the nested configuration class public.
- If it is an inner class, make it a public static nested class or a public top-level class.
- Flatten the nested fields into the parent class if nesting is not required.
Example fix
// before
public class AppProps {
class Security { private boolean enabled; }
}
// after
public class AppProps {
public static class Security { private boolean enabled;
public boolean isEnabled() { return enabled; }
public void setEnabled(boolean e) { enabled = e; } }
} Defensive patterns
Strategy: validation
Validate before calling
static void checkNestedConfigPublic(Class<?> props) {
for (Field f : props.getDeclaredFields()) {
Class<?> t = f.getType();
if (!t.isPrimitive() && !t.getName().startsWith("java.") && !Modifier.isPublic(t.getModifiers()))
throw new IllegalArgumentException("Nested config class " + t + " must be public");
}
} Prevention
- Declare nested configuration classes public (and static if nested).
- Ensure nested classes have public no-arg constructors and setters.
- Flatten nested structures when grouping is not essential.
When it happens
Trigger: populateConfigObject encounters a field whose type (fieldTypeClassInfo) has a no-arg constructor and is treated as a nested config object; Modifier.isPublic(fieldTypeClassInfo.flags()) is false, so it throws before recursing into the nested population.
Common situations: Package-private inner classes grouping related properties (e.g. AppProps.Security) in migrated Spring Boot apps; default (package) visibility on nested POJOs.
Related errors
- Class + configPropertiesClassInfo + which is annotated wit
- Class '' + configObjectClassStr + '' which is annotated with
- Configuration properties class '' + configClassInfo + '' doe
- Setter '' + setterName + '' of class '' + configClassInfo +
- A generic type is not allowed here; try creating a subclass
AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05).
Data as JSON: /api/errors/7b77ce7066a52736.
Report an issue: GitHub.