testcontainers/testcontainers-java · warning
Can not connect to Ryuk at
Error message
Can not connect to Ryuk at {}:{} What it means
RyukResourceReaper.maybeStart opens a socket to the Ryuk sidecar container to register cleanup filters. When connecting fails with an IOException, this warning is logged (inside an executor thread) and filter registration is retried/abandoned. Ryuk handles automatic container cleanup after the JVM exits; failure to connect means automatic reaping may not work for this session.
Solutions
- Check the Ryuk container status (`docker ps | grep ryuk`) and its logs for startup failures
- Set TESTCONTAINERS_HOST_OVERRIDE or verify ryuk.container.image / TESTCONTAINERS_RYUK_DISABLED settings in ~/.testcontainers.properties
- Ensure the host running tests can reach the port Ryuk is mapped to on the Docker host (critical for remote Docker)
- Update the Testcontainers version — newer releases have more robust Ryuk connection/retry handling
- Set TESTCONTAINERS_RYUK_DISABLED=true as a workaround and clean up containers manually
Example fix
// before: relying on Ryuk behind an unreachable remote Docker host
default behavior (ryuk enabled)
// after: ~/.testcontainers.properties
ryuk.disabled=true
// and add a @AfterAll stopAll in tests:
@AfterAll static void cleanup() { RyukResourceReaper.instance().performCleanup(); } Defensive patterns
Strategy: retry
Validate before calling
// probe reachability before relying on Ryuk
try (Socket s = new Socket()) { s.connect(new InetSocketAddress(ryukHost, ryukPort), 2000); return true; } catch (IOException e) { return false; } Try / catch
try (Socket socket = new Socket(host, ryukPort)) { /* register filters */ } catch (IOException e) { log.warn("Ryuk unreachable, falling back to manual cleanup"); } Prevention
- Verify the test host can reach the Docker host's mapped Ryuk port (especially remote DOCKER_HOST)
- Keep TESTCONTAINERS_RYUK_DISABLED consistent between local and CI
- Check Ryuk container logs when connection warnings appear
- Add manual container cleanup (@AfterAll / Reaper) as a fallback in CI
When it happens
Trigger: Ryuk container not started or crashed; TESTCONTAINERS_RYUK_DISABLED misconfiguration; network unreachable between JVM and Ryuk (custom networks, firewall, remote Docker host); Ryuk port not yet exposed when the first filter registration happens.
Common situations: Remote Docker (DOCKER_HOST over TCP/ssh) where the mapped Ryuk port isn't routable from the client; corporate proxies blocking the connection; Ryuk image pull failure leaving the helper container down; IPv6 vs IPv4 mismatch on localhost.
Understand the failure class
Background: ECONNREFUSED and "connection refused" / "could not connect to server" errors: what they mean and how to fix them — this error's family across 44 libraries.
Related errors
- Could 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/b87f14df423ee0ae.
Report an issue: GitHub.
Appendix: source
Thrown at core/src/main/java/org/testcontainers/utility/RyukResourceReaper.java:120
ResourceReaper.DEATH_NOTE.wait(1_000);
continue;
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
List<Map.Entry<String, String>> filters = ResourceReaper.DEATH_NOTE.get(index);
boolean isAcknowledged = registry.register(filters);
if (isAcknowledged) {
log.debug("Received 'ACK' from Ryuk");
ryukScheduledLatch.countDown();
index++;
} 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)