quarkusio/quarkus · error · IllegalStateException

Services have not been started yet

Error message

Services have not been started yet

What it means

ComposeProject.checkServicesStarted() throws IllegalStateException when queried before the Docker Compose project has actually created its service instances. It is a state guard: methods like waitUntilServicesReady, getEnvVarConfig, and getExposedPortConfig require start() to have completed and produced non-empty serviceInstances.

Source

Thrown at extensions/devservices/deployment/src/main/java/io/quarkus/devservices/deployment/compose/ComposeProject.java:224

                                    .map(c -> String.format("PORT_%d=%s", e.getKey().getPort(), c.getHostPortSpec())))
                            .collect(Collectors.joining("\n", "", "\n"));
                    if (!StringUtil.isNullOrEmpty(ports)) {
                        instance.copyFileToContainer(Transferable.of(ports.getBytes(StandardCharsets.UTF_8)),
                                exposedPortsPath);
                    }
                }
            }
        }
    }

    public void startAndWaitUntilServicesReady(Executor waitOn) {
        start();
        waitUntilServicesReady(waitOn);
    }

    private void checkServicesStarted() {
        if (serviceInstances == null || serviceInstances.isEmpty()) {
            throw new IllegalStateException("Services have not been started yet");
        }
    }

    private CompletableFuture<Void> waitOnThread(ComposeServiceWaitStrategyTarget instance, Executor waitOn) {
        if (waitOn == null) {
            return CompletableFuture.runAsync(() -> waitUntilReady(instance));
        } else {
            return CompletableFuture.runAsync(() -> waitUntilReady(instance), waitOn);
        }
    }

    private void waitUntilReady(ComposeServiceWaitStrategyTarget instance) {
        String serviceName = instance.getServiceName();
        final WaitStrategy strategy = waitStrategies.get(serviceName);
        if (strategy != null) {
            LOG.infov("Waiting for service {0} to be ready", serviceName);
            try {
                strategy.waitUntilReady(instance);

View on GitHub (pinned to e1c734241f)

Solutions

  1. Ensure start() (or startCompose()) completes successfully before reading env/port config
  2. Verify the Docker daemon is running (docker info) so compose can bring services up
  3. Check the compose file defines the expected services and they start without error
  4. If integrating with this class programmatically, guard with a started/ready flag or call start() idempotently before use

Example fix

// before
var env = composeProject.getEnvVarConfig();
// after
composeProject.start(); // or ensure started via the DevServices lifecycle
var env = composeProject.getEnvVarConfig();
Defensive patterns

Strategy: try-catch

Validate before calling

// ensure compose services exist before reading config
if (composeProject.getServiceInstances() == null || composeProject.getServiceInstances().isEmpty()) {
    composeProject.start();
}

Type guard

boolean isStarted(ComposeProject p) {
    var s = p.getServiceInstances();
    return s != null && !s.isEmpty();
}

Try / catch

try {
    var env = composeProject.getEnvVarConfig();
} catch (IllegalStateException e) {
    composeProject.start();
    var env = composeProject.getEnvVarConfig();
}

Prevention

When it happens

Trigger: Calling getEnvVarConfig() or getExposedPortConfig() (or waiting logic) on a ComposeProject whose start() was never invoked, failed before populating serviceInstances, or whose compose file defined zero running services.

Common situations: Docker daemon not running so start() produced no instances; custom DevServices code touching the ComposeProject directly before start; a compose file with services that failed to start, leaving the instance list empty.

Related errors


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