quarkusio/quarkus · error · IllegalArgumentException
Class '%s' which is used as %s in class '%s' must be a publi
Error message
Class '%s' which is used as %s in class '%s' must be a public class
What it means
Thrown by YamlListObjectHandler.validateClass when a class used as a nested Spring Boot properties type fails the public-visibility check. The handler supports deserializing spring-boot-properties YAML structures including generic list element types; the reflective/codegen binding path requires the element class (used as <member> in class <declaring class>) to be instantiable, so non-public classes (and interfaces and classes without no-arg constructors, checked by sibling guards) are rejected at build time.
Source
Thrown at extensions/spring-boot-properties/deployment/src/main/java/io/quarkus/spring/boot/properties/deployment/YamlListObjectHandler.java:211
});
});
}
});
}
private void validateClass(ClassInfo classInfo, Member member) {
if (Modifier.isInterface(classInfo.flags())) {
throw new IllegalArgumentException(
"The use of interfaces as the generic type of Lists fields / methods is not allowed. Offending field is '"
+ member.name() + "' of class '" + member.declaringClass().name().toString() + "'");
}
if (!classInfo.hasNoArgsConstructor()) {
throw new IllegalArgumentException(
String.format("Class '%s' which is used as %s in class '%s' must have a no-args constructor", classInfo,
member.phraseUsage(), member.declaringClass().name().toString()));
}
if (!Modifier.isPublic(classInfo.flags())) {
throw new IllegalArgumentException(
String.format("Class '%s' which is used as %s in class '%s' must be a public class", classInfo,
member.phraseUsage(), member.declaringClass().name().toString()));
}
}
private ClassInfo validateType(Type type) {
if (type.kind() != Type.Kind.PARAMETERIZED_TYPE) {
throw new IllegalArgumentException(ILLEGAL_ARGUMENT_MESSAGE);
}
ParameterizedType parameterizedType = (ParameterizedType) type;
if (!DotNames.LIST.equals(parameterizedType.name())) {
throw new IllegalArgumentException(ILLEGAL_ARGUMENT_MESSAGE);
}
if (parameterizedType.arguments().size() != 1) {
throw new IllegalArgumentException(ILLEGAL_ARGUMENT_MESSAGE);
}
ClassInfo classInfo = index.getClassByName(parameterizedType.arguments().get(0).name());
if (classInfo == null) {View on GitHub (pinned to e1c734241f)
Solutions
- Mark the element class public (for nested classes: public static class ...)
- Move the class to its own top-level public file
- Use a @ConfigMapping interface instead of class-based config
Example fix
// before
class ServerConfig { ... }
// after
public class ServerConfig { ... } Defensive patterns
Strategy: validation
Validate before calling
static void requirePublicClass(Class<?> c) {
if (!java.lang.reflect.Modifier.isPublic(c.getModifiers()))
throw new IllegalStateException(c + " must be public for YAML config binding");
} Type guard
boolean isPublicConcrete(Class<?> c) {
return java.lang.reflect.Modifier.isPublic(c.getModifiers()) && !c.isInterface();
} Try / catch
catch (IllegalArgumentException e) { if (e.getMessage().contains("must be a public class")) { /* make class public */ } throw e; } Prevention
- Declare config element classes public (public static nested classes)
- Review visibility when extracting nested config helper classes
When it happens
Trigger: A List<SomeClass> config member where SomeClass is package-private, protected, or private (e.g. a nested class without the public modifier) in a @ConfigProperties-processed class.
Common situations: Nested helper classes inside config classes declared without 'public', common when the nested class is only used internally.
Related errors
- Support for List of objects in classes annotated with '@Conf
- The use of interfaces as the generic type of Lists fields /
- Class '%s' which is used as %s in class '%s' must have a no-
- YamlListObjectHandler can only be used for fields / methods
- The class (${name}) cannot be created during deployment.
AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05).
Data as JSON: /api/errors/3a31739542891129.
Report an issue: GitHub.