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
- Ensure start() (or startCompose()) completes successfully before reading env/port config
- Verify the Docker daemon is running (docker info) so compose can bring services up
- Check the compose file defines the expected services and they start without error
- 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
- Always drive ComposeProject through its start()/DevServices lifecycle before querying it
- Verify the Docker daemon is reachable in dev/CI environments
- Inspect dev-mode logs for compose startup failures that leave services unstarted
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
- Services named ${servicesToWaitFor} do not exist, but wait c
- Docker Compose not found. Is ${composeExecutable} on the PAT
- Unsupported port format: ${port}
- Cannot create a RunningDevServicesDatasource before the H2 d
- OIDC Client Registration is closed
AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05).
Data as JSON: /api/errors/38de0e669392b60c.
Report an issue: GitHub.