{"record":{"id":"496528c03be19104","repo":"quarkusio/quarkus","slug":"the-configuration-clazz-is-missing-the-configm","errorCode":null,"errorMessage":"The configuration ${clazz} is missing the @ConfigMapping annotation","messagePattern":"The configuration (.+?) is missing the @ConfigMapping annotation","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"core/deployment/src/main/java/io/quarkus/deployment/configuration/BuildTimeConfigurationReader.java","lineNumber":70,"sourceCode":"\n    private static List<Class<?>> collectConfigRoots(ClassLoader classLoader) throws IOException, ClassNotFoundException {\n        Assert.checkNotNullParam(\"classLoader\", classLoader);\n        // populate with all known types\n        List<Class<?>> roots = new ArrayList<>();\n        for (Class<?> clazz : ServiceUtil.classesNamedIn(classLoader, CONFIG_ROOTS_LIST)) {\n            if (!clazz.isInterface()) {\n                throw new IllegalArgumentException(\n                        \"The configuration \" + clazz + \" must be an interface annotated with @ConfigRoot and @ConfigMapping\");\n            }\n\n            ConfigRoot configRoot = clazz.getAnnotation(ConfigRoot.class);\n            if (configRoot == null) {\n                throw new IllegalArgumentException(\"The configuration \" + clazz + \" is missing the @ConfigRoot annotation\");\n            }\n\n            ConfigMapping configMapping = clazz.getAnnotation(ConfigMapping.class);\n            if (configMapping == null) {\n                throw new IllegalArgumentException(\"The configuration \" + clazz + \" is missing the @ConfigMapping annotation\");\n            }\n\n            roots.add(clazz);\n        }\n        return roots;\n    }\n\n    private final ClassLoader classLoader;\n\n    private final List<ConfigClass> buildTimeMappings;\n    private final List<ConfigClass> buildTimeRunTimeMappings;\n    private final List<ConfigClass> runTimeMappings;\n    private final List<ConfigClass> buildTimeVisibleMappings;\n    private final Set<String> mappingsIgnorePaths;\n\n    final ConfigTrackingInterceptor buildConfigTracker;\n\n    /**","sourceCodeStart":52,"sourceCodeEnd":88,"githubUrl":"https://github.com/quarkusio/quarkus/blob/e1c734241f34c7919086ceb4c9262b4a58f6de44/core/deployment/src/main/java/io/quarkus/deployment/configuration/BuildTimeConfigurationReader.java#L52-L88","documentation":"collectConfigRoots in BuildTimeConfigurationReader requires each config root class to be annotated with both @ConfigRoot and @ConfigMapping. When @ConfigRoot is present but the SmallRye @ConfigMapping annotation is missing, this IllegalArgumentException is thrown. @ConfigMapping is what turns the interface into a typed mapping of configuration properties.","triggerScenarios":"A configuration interface registered as a build-time config root has @ConfigRoot but no @ConfigMapping annotation, e.g. an older-style config interface migrated to the new @ConfigMapping model without adding the annotation.","commonSituations":"Migrating legacy @ConfigRoot/@ConfigItem classes to the @ConfigMapping model and only partially updating annotations; hand-writing config interfaces for extensions.","solutions":["Add @ConfigMapping(prefix = \"<prefix>\") to the configuration interface alongside @ConfigRoot.","Convert any remaining @ConfigItem fields into interface methods (the @ConfigMapping style).","Verify the extension is not still registering a class-based config object where an interface is expected."],"exampleFix":"// before\n@ConfigRoot(phase = ConfigPhase.BUILD_TIME)\npublic interface MyConfig { String name(); }\n\n// after\n@ConfigRoot(phase = ConfigPhase.BUILD_TIME)\n@ConfigMapping(prefix = \"myapp\")\npublic interface MyConfig { String name(); }","handlingStrategy":"validation","validationCode":"MyConfig.class.isAnnotationPresent(ConfigRoot.class)\n    && MyConfig.class.isAnnotationPresent(ConfigMapping.class);","typeGuard":"static boolean hasConfigMapping(Class<?> c) {\n    return c.isAnnotationPresent(ConfigMapping.class);\n}","tryCatchPattern":null,"preventionTips":["When migrating from legacy @ConfigRoot classes, add @ConfigMapping in the same change.","Copy the annotation pair from an existing working extension config interface.","Run the extension's deployment tests after any config annotation change."],"tags":["quarkus","configuration","annotation","config-mapping"],"backgroundTag":"missing-annotation","analyzedSha":"e1c734241f34c7919086ceb4c9262b4a58f6de44","analyzedAt":"2026-09-05T17:01:29.979Z","contentChangedAt":"2026-09-05T17:01:29.979Z","schemaVersion":2},"datasetVersion":"2026-09-12T22:17:10.623Z"}