quarkusio/quarkus · error · IllegalStateException

Dev services for ${request.getName()} requires a startable s

Error message

Dev services for ${request.getName()} requires a startable supplier, but none was provided.

What it means

DevServicesRegistryBuildItem.reallyStart starts a dev service (e.g. a database container) during Quarkus dev/test mode. It requires the DevServicesRequest to carry a Supplier<Startable>; if none was set, the registry has no way to actually start the service and throws this IllegalStateException immediately at startup. This is an internal programming/extension contract violation, not a user config problem.

Source

Thrown at core/deployment/src/main/java/io/quarkus/deployment/builditem/DevServicesRegistryBuildItem.java:181

                        .provide(reusedConfig);
                if (!extraFromBuildItem.isEmpty()) {
                    reusedConfig.putAll(extraFromBuildItem);
                }
            }

            config.putAll(reusedConfig);
            overrideConfig.putAll(matchedDevService.overrideConfigs());
        }
    }

    private void reallyStart(DevServicesResultBuildItem request, List<DevServicesCustomizerBuildItem> customizers,
            List<DevServicesAdditionalConfigBuildItem> additionalConfigBuildItems, Map<String, String> allDevServicesConfig,
            Map<String, String> allDevServicesOverrideConfigs) {
        StartupLogCompressor compressor = new StartupLogCompressor("Dev Services Startup", null, null);
        try {
            Supplier<Startable> startableSupplier = request.getStartableSupplier();
            if (startableSupplier == null) {
                throw new IllegalStateException(
                        "Dev services for " + request.getName() + " requires a startable supplier, but none was provided.");
            }
            Startable startable = startableSupplier.get();
            for (DevServicesCustomizerBuildItem customizer : customizers) {
                startable = customizer.apply(request, startable);
            }

            String missingDependency = null;

            // The config from the new sources isn't easily available via ConfigProvider.getConfig(), so directly inject it into services which depend on it
            var dependencies = request.getDependencies();
            if (dependencies != null && !dependencies.isEmpty()) {
                for (DevServicesResultBuildItem.DevServiceConfigDependency<? extends Startable> dependency : dependencies) {

                    var value = allDevServicesConfig.get(dependency.requiredConfigKey());
                    if (value != null) {
                        ((BiConsumer<Startable, String>) dependency.valueInjector()).accept(startable, value);
                    } else {

View on GitHub (pinned to e1c734241f)

Solutions

  1. Set a startable supplier on the request, e.g. DevServicesRequest with .startableSupplier(() -> new MyStartable(...)) before calling start.
  2. If you only need config from a service already managed elsewhere, use the appropriate existing DevServicesResultBuildItem instead of registering a new request without a supplier.
  3. Check the Quarkus version/extension for a known bug and upgrade if this is thrown by framework code you did not modify.

Example fix

// before
DevServicesRequest request = DevServicesRequest.of("my-db", featurePriority);
registry.start(request);
// after
DevServicesRequest request = DevServicesRequest.of("my-db", featurePriority)
        .startableSupplier(() -> new DataSourceStartable(config));
registry.start(request);
Defensive patterns

Strategy: validation

Validate before calling

if (request.getStartableSupplier() == null) {
    throw new IllegalStateException("DevServicesRequest '" + request.getName() + "' is missing its startable supplier; add .startableSupplier(...) before calling start()");
}

Try / catch

try {
    registry.start(request);
} catch (IllegalStateException e) {
    if (e.getMessage() != null && e.getMessage().contains("requires a startable supplier")) {
        // fix request construction; this is a build-time programming error, do not retry
    }
    throw e;
}

Prevention

When it happens

Trigger: Calling DevServicesRegistryBuildItem.start (directly or via the registry) with a request built without DevServicesRequest.startableSupplier(...) — the supplier is null when reallyStart runs.

Common situations: Custom extension code or a modified Quarkus build constructing a dev-services request programmatically while forgetting to supply the Startable supplier; regressions in Quarkus core or an extension after refactoring how dev services are registered.

Related errors


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