quarkusio/quarkus · error · IllegalStateException
Unable to scan config mapping without config root: ${configM
Error message
Unable to scan config mapping without config root: ${configMappingWithoutConfigRoot} What it means
The processor failed while scanning @ConfigMapping classes that have no corresponding @ConfigRoot. To document them, it fabricates a dummy DiscoveryConfigRoot and scans the mapping; any exception in that scan is wrapped in this IllegalStateException naming the mapping interface.
Source
Thrown at core/processor/src/main/java/io/quarkus/annotation/processor/documentation/config/scanner/ConfigAnnotationScanner.java:151
continue;
}
if (isConfigMappingWithoutConfigRootAlreadyHandled(configMappingWithoutConfigRoot)) {
continue;
}
debug("Detected config mapping without config root: " + configMappingWithoutConfigRoot,
configMappingWithoutConfigRoot);
try {
// we need to forge a dummy DiscoveryConfigRoot, it's mostly ignored in the listeners
DiscoveryConfigRoot discoveryConfigRoot = new DiscoveryConfigRoot(config.getExtension(), "dummy", "dummy",
utils.element().getBinaryName(configMappingWithoutConfigRoot),
configMappingWithoutConfigRoot.getQualifiedName().toString(),
ConfigPhase.BUILD_TIME, null);
scanElement(configMappingWithoutConfigRootListeners, discoveryConfigRoot, configMappingWithoutConfigRoot);
} catch (Exception e) {
throw new IllegalStateException(
"Unable to scan config mapping without config root: " + configMappingWithoutConfigRoot, e);
}
}
}
public ConfigCollector finalizeProcessing() {
applyListeners(configRootListeners, l -> l.finalizeProcessing());
applyListeners(configMappingWithoutConfigRootListeners, l -> l.finalizeProcessing());
return configCollector;
}
private void scanElement(List<ConfigAnnotationListener> listeners, DiscoveryRootElement configRootElement,
TypeElement clazz) {
// we scan the superclass and interfaces first so that the local elements can potentially override them
if (clazz.getKind() == ElementKind.INTERFACE) {
List<? extends TypeMirror> superInterfaces = clazz.getInterfaces();
for (TypeMirror superInterface : superInterfaces) {View on GitHub (pinned to e1c734241f)
Solutions
- Read the 'Caused by' chain to find the real failure inside the mapping scan.
- Check every property type in the named interface is a supported config type and that referenced enums are simple/registered.
- Ensure any referenced nested groups are visible/resolvable at processing time (avoid referencing classes not yet compiled).
- Clean rebuild to eliminate stale generated sources.
- If a supported pattern fails, reduce the interface and file a Quarkus issue with the reproducer.
Example fix
// before: type the scanner cannot document
@ConfigMapping(prefix = "app")
public interface AppConfig {
Optional<List<MyOpaqueClass>> items(); // fails
}
// after
@ConfigMapping(prefix = "app")
public interface AppConfig {
Optional<List<Integer>> items();
} Defensive patterns
Strategy: validation
Validate before calling
// scan mapping interfaces for unsupported shapes before compiling
for (var m : AppConfig.class.getDeclaredMethods()) {
Class<?> t = m.getReturnType();
if (t == Optional.class && !isSupportedConfigType(genericArg(m)))
throw new IllegalStateException("Unsupported mapping type: " + m);
} Type guard
static boolean isDocumentableMapping(Class<?> c) {
return c.isAnnotationPresent(ConfigMapping.class)
&& Arrays.stream(c.getDeclaredMethods())
.allMatch(m -> isSupportedConfigType(m.getReturnType()));
} Prevention
- Keep @ConfigMapping property types simple and supported.
- Avoid referencing not-yet-generated classes from mappings.
- Reference enums directly as property types so they get registered.
- Rebuild cleanly after Quarkus upgrades.
When it happens
Trigger: Compiling an application with a @ConfigMapping interface (no @ConfigRoot) whose members trip the scanner: unsupported property types, unregistered enums, recursive/nested groups that cannot be resolved, or Javadoc listeners failing on that element.
Common situations: Application developers using @ConfigMapping for app config; a mapping with an exotic type like Optional<List<SomeUnregisteredClass>>; mappings referencing generated sources that are not on the annotation-processing path; Quarkus upgrade changing scan behavior.
Related errors
- Unable to scan config group: ${configGroup}
- Unable to scan config root: ${configRoot}
- Unable to parse: ${resolvedModelPath}
- Multiple listeners returned discovery root elements for: ${d
- No listeners returned a discovery root element
AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05).
Data as JSON: /api/errors/1f34416bb997d10b.
Report an issue: GitHub.