quarkusio/quarkus · critical · IllegalArgumentException

Starting with Quarkus 3.25, legacy config classes (deprecate

Error message

Starting with Quarkus 3.25, legacy config classes (deprecated since Quarkus 3.19) are not supported anymore. Please migrate the configuration of your extension to interfaces annotated with @ConfigMapping. See https://quarkus.io/guides/config-mappings#config-mappings for more information.

What it means

The Quarkus extension annotation processor now hard-fails at build time when an extension still uses legacy @ConfigRoot config classes. Legacy config classes (deprecated since Quarkus 3.19) are unsupported as of Quarkus 3.25; extensions must migrate to @ConfigMapping interfaces.

Source

Thrown at core/processor/src/main/java/io/quarkus/annotation/processor/ExtensionAnnotationProcessor.java:47

@SupportedOptions({ Options.LEGACY_CONFIG_ROOT, Options.GENERATE_DOC, Options.SPLIT_ON_CONFIG_ROOT_DESCRIPTION })
public class ExtensionAnnotationProcessor extends AbstractProcessor {

    private static final String DEBUG = "debug-extension-annotation-processor";

    private Utils utils;
    private List<ExtensionProcessor> extensionProcessors;

    @Override
    public synchronized void init(ProcessingEnvironment processingEnv) {
        super.init(processingEnv);

        utils = new Utils(processingEnv);

        boolean useConfigMapping = !Boolean
                .parseBoolean(utils.processingEnv().getOptions().getOrDefault(Options.LEGACY_CONFIG_ROOT, "false"));

        if (!useConfigMapping) {
            throw new IllegalArgumentException(
                    "Starting with Quarkus 3.25, legacy config classes (deprecated since Quarkus 3.19) are not supported anymore. "
                            + "Please migrate the configuration of your extension to interfaces annotated with @ConfigMapping. See https://quarkus.io/guides/config-mappings#config-mappings for more information.");
        }

        boolean debug = Boolean.getBoolean(DEBUG);

        ExtensionModule extensionModule = utils.extension().getExtensionModule();

        Config config = new Config(extensionModule, debug);

        List<ExtensionProcessor> extensionProcessors = new ArrayList<>();
        extensionProcessors.add(new ExtensionBuildProcessor());

        boolean generateDoc = !"false".equals(processingEnv.getOptions().get(Options.GENERATE_DOC));

        // for now, we generate the old config doc by default but we will change this behavior soon
        if (generateDoc) {
            if (extensionModule.detected()) {

View on GitHub (pinned to e1c734241f)

Solutions

  1. Migrate the extension's config classes to interfaces annotated with @ConfigMapping per https://quarkus.io/guides/config-mappings
  2. Temporarily pass -AlegacyConfigRoot=true to keep the old behavior while migrating (short-term only)
  3. Pin to a pre-3.25 Quarkus version until migration is feasible
  4. Use the quarkus-maven-plugin / config migration guidance to auto-convert config classes

Example fix

// before
@ConfigRoot(name = "myext", phase = ConfigPhase.BUILD_AND_RUN_TIME_FIXED)
public class MyExtConfig {
    @ConfigItem public String name;
}
// after
@ConfigMapping(prefix = "myext")
public interface MyExtConfig {
    String name();
}
Defensive patterns

Strategy: validation

Validate before calling

// Ensure no legacy config classes remain before upgrading:
grep -rl "@ConfigRoot" extensions/*/runtime/src/main/java || echo "OK: no legacy config roots"

Prevention

When it happens

Trigger: Building an extension whose config classes extend ConfigRoot with the annotation processor active, without setting Options.LEGACY_CONFIG_ROOT=true; the processor's init() throws immediately.

Common situations: Upgrading a custom/third-party Quarkus extension from 3.19–3.24 to 3.25+ while keeping old @ConfigRoot classes; vendoring an unmaintained extension into a new build.

Related errors


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