testcontainers/testcontainers-java · critical · IllegalStateException
Could not connect to Ryuk at
Error message
Could not connect to Ryuk at %s:%s
What it means
Ryuk is Testcontainers' sidecar container that reaps orphaned containers/networks/volumes after the JVM exits. In RyukResourceReaper.maybeStart the client thread signals readiness via ryukScheduledLatch; if the latch is not counted down within ryuk.timeout seconds, Testcontainers concludes the Ryuk container never became reachable and throws this IllegalStateException, failing container startup.
Solutions
- Verify the Ryuk image (testcontainers/ryuk:*) can be pulled: docker pull it manually / configure a registry mirror
- If Ryuk cannot run in your environment, set TESTCONTAINERS_RYUK_DISABLED=true (in ~/.testcontainers.properties) — you then own cleanup of stopped containers
- Increase the wait via testcontainers.properties `ryuk.timeout` or env TESTCONTAINERS_RYUK_TIMEOUT
- Check network reachability from the JVM to the Docker host/port (firewall, DOCKER_HOST misconfiguration, proxy settings)
Example fix
// before // tests fail: Could not connect to Ryuk at 172.17.0.1:32768 // after (testcontainers.properties) ryuk.disabled=true // or ryuk.timeout=120
Defensive patterns
Strategy: retry
Validate before calling
// before tests: verify Ryuk image is pullable and Docker host reachable docker pull testcontainers/ryuk:0.11.0 nc -z <docker-host> <port> || echo "Ryuk port unreachable"
Try / catch
try {
container.start();
} catch (IllegalStateException e) {
if (e.getMessage().startsWith("Could not connect to Ryuk")) {
log.warn("Ryuk unavailable; disabling and retrying", e);
// restart with ryuk.disabled=true in testcontainers.properties
} else throw e;
} Prevention
- Pre-pull the Ryuk image in CI and configure registry mirrors for air-gapped environments
- Increase ryuk.timeout for slow image pulls
- Disable Ryuk on remote/restricted Docker hosts and handle cleanup yourself
- Check firewall/proxy rules between JVM and Docker host
When it happens
Trigger: Starting any container when Ryuk is enabled and: the Ryuk image cannot be pulled (offline/private registry), the host port for Ryuk is not reachable (firewall, remote Docker host without exposed port), Ryuk fails to boot (incompatible image/arch), or the configured timeout is too short.
Common situations: CI runners with restrictive networking to remote Docker (DOCKER_HOST over ssh/tcp); air-gapped environments without the testcontainers/ryuk image in a local mirror; enterprise proxies blocking the connection; slow image pulls exceeding the default timeout.
Understand the failure class
Background: Request timed out: what client-side request timeouts mean across libraries (Request timed out, TIMED_OUT, APITimeoutError) — this error's family across 39 libraries.
Related errors
- Can not connect to Ryuk at
- Failed to pull image
- Elasticsearch container has no network configuration
- Elasticsearch container is not connected to the expected…
- Failed to connect Elasticsearch container to ad-hoc shared…
AI-assisted analysis of testcontainers/testcontainers-java@8e549514e3 (2026-09-12).
Data as JSON: /api/errors/f77b0e73851f5834.
Report an issue: GitHub.
Appendix: source
Thrown at core/src/main/java/org/testcontainers/utility/RyukResourceReaper.java:132
} else {
log.debug("Didn't receive 'ACK' from Ryuk. Will retry to send filters.");
}
}
}
} catch (IOException e) {
log.warn("Can not connect to Ryuk at {}:{}", host, ryukPort, e);
}
});
}
},
"testcontainers-ryuk"
);
kiraThread.setDaemon(true);
kiraThread.start();
// We need to wait before we can start any containers to make sure that we delete them
if (!ryukScheduledLatch.await(TestcontainersConfiguration.getInstance().getRyukTimeout(), TimeUnit.SECONDS)) {
log.error("Timed out waiting for Ryuk container to start. Ryuk's logs:\n{}", ryukContainer.getLogs());
throw new IllegalStateException(String.format("Could not connect to Ryuk at %s:%s", host, ryukPort));
}
}
}
View on GitHub (pinned to 8e549514e3)