quarkusio/quarkus · error · IllegalArgumentException

The configuration ${clazz} is missing the @ConfigRoot annota

Error message

The configuration ${clazz} is missing the @ConfigRoot annotation

What it means

During build-time configuration scanning, collectConfigRoots in BuildTimeConfigurationReader inspects every configuration class and requires it to carry the @ConfigRoot annotation. When a class passed in the config roots set lacks @ConfigRoot (while possibly having @ConfigMapping), the reader rejects it with this IllegalArgumentException. @ConfigRoot supplies the extension name and phase metadata Quarkus needs to map config interfaces to their quarkus.* prefix.

Source

Thrown at core/deployment/src/main/java/io/quarkus/deployment/configuration/BuildTimeConfigurationReader.java:65

/**
 * A configuration reader.
 */
public final class BuildTimeConfigurationReader {
    private static final String CONFIG_ROOTS_LIST = "META-INF/quarkus-config-roots.list";

    private static List<Class<?>> collectConfigRoots(ClassLoader classLoader) throws IOException, ClassNotFoundException {
        Assert.checkNotNullParam("classLoader", classLoader);
        // populate with all known types
        List<Class<?>> roots = new ArrayList<>();
        for (Class<?> clazz : ServiceUtil.classesNamedIn(classLoader, CONFIG_ROOTS_LIST)) {
            if (!clazz.isInterface()) {
                throw new IllegalArgumentException(
                        "The configuration " + clazz + " must be an interface annotated with @ConfigRoot and @ConfigMapping");
            }

            ConfigRoot configRoot = clazz.getAnnotation(ConfigRoot.class);
            if (configRoot == null) {
                throw new IllegalArgumentException("The configuration " + clazz + " is missing the @ConfigRoot annotation");
            }

            ConfigMapping configMapping = clazz.getAnnotation(ConfigMapping.class);
            if (configMapping == null) {
                throw new IllegalArgumentException("The configuration " + clazz + " is missing the @ConfigMapping annotation");
            }

            roots.add(clazz);
        }
        return roots;
    }

    private final ClassLoader classLoader;

    private final List<ConfigClass> buildTimeMappings;
    private final List<ConfigClass> buildTimeRunTimeMappings;
    private final List<ConfigClass> runTimeMappings;
    private final List<ConfigClass> buildTimeVisibleMappings;

View on GitHub (pinned to e1c734241f)

Solutions

  1. Add @ConfigRoot(phase = ConfigPhase.BUILD_TIME (or RUN_TIME as appropriate), prefix = "<extension>") to the configuration interface.
  2. Ensure the class is actually an interface; @ConfigRoot on classes is not the intended usage.
  3. Rebuild the deployment module so the annotation is processed by the CollectBuildTimeConfig build step.

Example fix

// before
@ConfigMapping(prefix = "myext")
public interface MyExtConfig { }

// after
@ConfigRoot(phase = ConfigPhase.BUILD_TIME, prefix = "myext")
@ConfigMapping(prefix = "myext")
public interface MyExtConfig { }
Defensive patterns

Strategy: validation

Validate before calling

MyConfig.class.isInterface()
    && MyConfig.class.isAnnotationPresent(ConfigRoot.class)
    && MyConfig.class.isAnnotationPresent(ConfigMapping.class);

Type guard

static boolean isConfigRoot(Class<?> c) {
    return c.isInterface() && c.isAnnotationPresent(ConfigRoot.class);
}

Prevention

When it happens

Trigger: An interface implementing application configuration is registered as a config root (via the ConfigClassBuildItem / CollectBuildTimeConfig build step) but is only annotated with @ConfigMapping, missing @ConfigRoot(phase = ..., prefix = ...).

Common situations: Extension authors writing a custom @ConfigMapping interface and forgetting the required @ConfigRoot annotation; copying a Spring Boot @ConfigurationProperties-style class into Quarkus; refactoring that removes annotations thought to be optional.

Related errors


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