quarkusio/quarkus · error · IllegalArgumentException

Class '' + configObjectClassStr + '' which is annotated with

Error message

Class '' + configObjectClassStr + '' which is annotated with '' + ConfigurationPropertiesProcessor.CONFIGURATION_PROPERTIES + '' must be public, as must be the case for all of its super classes

What it means

Configuration properties classes are instantiated reflectively at build time and (in native mode) must be visible to reflection. The @ConfigurationProperties class — and every class in its hierarchy up to Object — must be public; a package-private or protected class breaks instantiation and is rejected at build.

Source

Thrown at extensions/spring-boot-properties/deployment/src/main/java/io/quarkus/spring/boot/properties/deployment/ClassConfigurationPropertiesUtil.java:256

            ConfigMapping.NamingStrategy namingStrategy,
            boolean failOnMismatchingMember,
            ConfigurationPropertiesMetadataBuildItem.InstanceFactory instanceFactory, BlockCreator bc, Expr configParam) {
        String configObjectClassStr = configClassInfo.name().toString();
        LocalVar configObject;
        if (instanceFactory == null) {
            configObject = bc.localVar("configObject", bc.new_(ConstructorDesc.of(ClassDesc.of(configObjectClassStr))));
        } else {
            configObject = bc.localVar("configObject", instanceFactory.apply(bc, configObjectClassStr));
        }

        // Fields with a default value will be removed from this list at the end of the method.
        List<ConfigPropertyBuildItemCandidate> configPropertyBuildItemCandidates = new ArrayList<>();

        // go up the class hierarchy until we reach Object
        ClassInfo currentClassInHierarchy = configClassInfo;
        while (true) {
            if (!Modifier.isPublic(currentClassInHierarchy.flags())) {
                throw new IllegalArgumentException(
                        "Class '" + configObjectClassStr + "' which is annotated with '"
                                + ConfigurationPropertiesProcessor.CONFIGURATION_PROPERTIES
                                + "' must be public, as must be the case for all of its super classes");
            }

            // For each field of the class try to pull it out of MP Config and call the corresponding setter
            List<FieldInfo> fields = currentClassInHierarchy.fields();
            for (FieldInfo field : fields) {
                if (Modifier.isStatic(field.flags())) { // nothing we need to do about static fields
                    continue;
                }
                AnnotationInstance configPropertyAnnotation = field.annotation(DotNames.CONFIG_PROPERTY);
                if (configPropertyAnnotation != null) {
                    AnnotationValue configPropertyDefaultValue = configPropertyAnnotation.value("defaultValue");
                    if ((configPropertyDefaultValue != null)
                            && !configPropertyDefaultValue.asString().equals(ConfigProperty.UNCONFIGURED_VALUE)) {
                        LOGGER.warn(
                                "'defaultValue' of '@ConfigProperty' is ignored when added to a field of a class annotated with '@ConfigProperties'. Offending field is '"

View on GitHub (pinned to e1c734241f)

Solutions

  1. Make the @ConfigurationProperties class public.
  2. Make every non-public superclass in its hierarchy public.
  3. Move a previously nested/inner properties class out to a top-level public class.

Example fix

// before
class AppProps { ... }
// after
public class AppProps { ... }
Defensive patterns

Strategy: validation

Validate before calling

static void checkPublicHierarchy(Class<?> c) {
    for (Class<?> k = c; k != Object.class; k = k.getSuperclass()) {
        if (!Modifier.isPublic(k.getModifiers()))
            throw new IllegalArgumentException(k + " must be public");
    }
}

Prevention

When it happens

Trigger: populateConfigObject walks the class hierarchy of the config object class and throws as soon as any currentClassInHierarchy fails Modifier.isPublic(...).

Common situations: Nesting a package-private properties class inside another class; narrowing visibility of a superclass during refactoring; Kotlin/Java inner classes with restricted access.

Related errors


AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05). Data as JSON: /api/errors/60e4194695170066. Report an issue: GitHub.