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

  1. Read the 'Caused by' chain to find the real failure inside the mapping scan.
  2. Check every property type in the named interface is a supported config type and that referenced enums are simple/registered.
  3. Ensure any referenced nested groups are visible/resolvable at processing time (avoid referencing classes not yet compiled).
  4. Clean rebuild to eliminate stale generated sources.
  5. 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

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


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