quarkusio/quarkus · error · IllegalStateException

The 'RolesAllowedConfigExpStorage' bean is created before ru

Error message

The 'RolesAllowedConfigExpStorage' bean is created before runtime configuration is ready

What it means

RolesAllowedConfigExpStorage caches resolved security-role configuration expressions for the RESTEasy Reactive Jackson server. Quarkus initializes this singleton bean itself only once runtime configuration is ready; the Supplier's get() throws IllegalStateException if the bean is requested before that initialization ran, indicating a lifecycle/wiring bug (bean created too early) rather than user misconfiguration.

Source

Thrown at extensions/resteasy-reactive/rest-jackson/runtime/src/main/java/io/quarkus/resteasy/reactive/jackson/runtime/ResteasyReactiveServerJacksonRecorder.java:58

        return new BiConsumer<>() {
            @Override
            public void accept(String configKey, Supplier<String[]> configValueSupplier) {
                configExpToAllowedRoles.getValue().put(configKey, configValueSupplier);
            }
        };
    }

    @StaticInit
    public Supplier<RolesAllowedConfigExpStorage> createRolesAllowedConfigExpStorage(
            RuntimeValue<Map<String, Supplier<String[]>>> configExpToAllowedRoles) {
        return new Supplier<>() {
            @Override
            public RolesAllowedConfigExpStorage get() {
                Map<String, Supplier<String[]>> map = configExpToAllowedRoles.getValue();
                if (map.isEmpty()) {
                    // there is no reason why this should happen, because we initialize the bean ourselves
                    // when runtime configuration is ready
                    throw new IllegalStateException(
                            "The 'RolesAllowedConfigExpStorage' bean is created before runtime configuration is ready");
                }
                return new RolesAllowedConfigExpStorage(configExpToAllowedRoles.getValue());
            }
        };
    }

    @RuntimeInit
    public void initAndValidateRolesAllowedConfigExp() {
        Arc.container().instance(RolesAllowedConfigExpStorage.class).get().resolveRolesAllowedConfigExp();
    }

    public void recordJsonView(String targetId, String className) {
        jsonViewMap.put(targetId, loadClass(className));
    }

    public void recordCustomSerialization(String target, String className) {
        customSerializationMap.put(target, loadClass(className));

View on GitHub (pinned to e1c734241f)

Solutions

  1. Ensure you do not inject/observe the internal RolesAllowedConfigExpStorage bean directly; treat it as internal API
  2. Check for custom extensions or producers that touch RolesAllowedConfigExpStorage earlier in startup and delay them (observe RuntimeConfigReady event or use @AllowsConfigInjection patterns)
  3. Verify that any @RolesAllowed / config-expression security setup is declared normally (application.properties values present) so runtime config resolves on time
  4. If it occurs in a stock app, isolate a reproducer and report a Quarkus bug — this indicates an initialization-order regression

Example fix

// before
@ApplicationScoped
class MyBean {
    RolesAllowedConfigExpStorage storage; // early injection of internal bean
}

// after
@ApplicationScoped
class MyBean {
    void onStart(@Observes RuntimeConfigReady ev) { /* access config-dependent state here */ }
}
Defensive patterns

Strategy: try-catch

Try / catch

try {
    RolesAllowedConfigExpStorage s = storageSupplier.get();
} catch (IllegalStateException e) {
    if (e.getMessage() != null && e.getMessage().contains("runtime configuration is ready")) {
        // defer access until runtime config is initialized (e.g. observe RuntimeConfigReady)
    }
}

Prevention

When it happens

Trigger: A RolesAllowedConfigExpStorage bean instance is obtained from the generated Supplier before the RuntimeConfigSetup run-time init step populated the config-expression map (e.g. due to a CDI bean ordering issue, custom producer, or extension regression).

Common situations: Using quarkus.http.auth... or @RolesAllowed with property expressions (e.g. ${admin.roles}) in combination with custom security extensions; upgrading Quarkus where bean init ordering changed; user code injecting this internal storage bean directly.

Related errors


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