testcontainers/testcontainers-java · error · IllegalStateException

Cannot obtain endpoint URL

Error message

Cannot obtain endpoint URL

What it means

LocalStackContainer.getEndpoint() resolves the container host to an IP address and builds an http:// URI with the mapped port. If DNS resolution of the host fails (UnknownHostException) or the resulting URI is malformed (URISyntaxException), it wraps the cause in this IllegalStateException. It exists so callers get a single clear failure when the LocalStack endpoint cannot be constructed.

Solutions

  1. Call container.start() before invoking getEndpoint()
  2. Check that your Docker host (DOCKER_HOST / docker context) points to a resolvable hostname; inspect the wrapped UnknownHostException in the exception cause
  3. Fix DNS/hosts resolution for the Docker host (add an /etc/hosts entry or use an IP-based DOCKER_HOST)
  4. If constructing the URI yourself elsewhere, validate the host string before use

Example fix

// before
LocalStackContainer container = new LocalStackContainer(DockerImageName.parse("localstack/localstack"));
URI endpoint = container.getEndpoint(); // IllegalStateException: Cannot obtain endpoint URL
// after
LocalStackContainer container = new LocalStackContainer(DockerImageName.parse("localstack/localstack"));
container.start();
URI endpoint = container.getEndpoint();
Defensive patterns

Strategy: try-catch

Validate before calling

if (!container.isRunning()) {
    throw new IllegalStateException("Start the LocalStackContainer before calling getEndpoint()");
}

Try / catch

try {
    URI endpoint = container.getEndpoint();
} catch (IllegalStateException e) {
    throw new AssertionError("LocalStack endpoint unavailable: " + e.getCause(), e);
}

Prevention

When it happens

Trigger: Calling getEndpoint() before the container is started (getMappedPort returns nothing meaningful / host unresolvable), or when the Docker host hostname cannot be resolved by InetAddress.getByName (bad docker.host config, DNS issues in the environment, or an unresolvable address from DOCKER_HOST).

Common situations: Tests that call getEndpoint() in a @BeforeAll before container.start(); CI environments where the Docker daemon host string (e.g. tcp://some-proxy) is not resolvable; custom DOCKER_HOST settings with odd hostnames; VPN or corporate DNS blocking resolution.

Understand the failure class

Background: "Invalid URL" / "URL cannot be empty": fix the malformed or missing URL behind request-construction failures — this error's family across 50 libraries.

Related errors


AI-assisted analysis of testcontainers/testcontainers-java@8e549514e3 (2026-09-12). Data as JSON: /api/errors/b554c060e9acf48c. Report an issue: GitHub.

Appendix: source

Thrown at modules/localstack/src/main/java/org/testcontainers/localstack/LocalStackContainer.java:161

             localstack.getAccessKey(), localstack.getSecretKey()
             )))
             .region(Region.of(localstack.getRegion()))
             .build()
             </code></pre>
     * <p><strong>Please note that this method is only intended to be used for configuring AWS SDK clients
     * that are running on the test host. If other containers need to call this one, they should be configured
     * specifically to do so using a Docker network and appropriate addressing.</strong></p>
     *
     * @return an {@link URI} endpoint
     */
    public URI getEndpoint() {
        try {
            final String address = getHost();
            // resolve IP address and use that as the endpoint so that path-style access is automatically used for S3
            String ipAddress = InetAddress.getByName(address).getHostAddress();
            return new URI("http://" + ipAddress + ":" + getMappedPort(PORT));
        } catch (UnknownHostException | URISyntaxException e) {
            throw new IllegalStateException("Cannot obtain endpoint URL", e);
        }
    }

    /**
     * Provides a default access key that is preconfigured to communicate with a given simulated service.
     * <a href="https://github.com/localstack/localstack/blob/master/doc/interaction/README.md?plain=1#L32">AWS Access Key</a>
     * The access key can be used to construct AWS SDK v2 clients:
     * <pre><code>S3Client s3 = S3Client
             .builder()
             .endpointOverride(localstack.getEndpoint())
             .credentialsProvider(StaticCredentialsProvider.create(AwsBasicCredentials.create(
             localstack.getAccessKey(), localstack.getSecretKey()
             )))
             .region(Region.of(localstack.getRegion()))
             .build()
     </code></pre>
     * @return a default access key
     */

View on GitHub (pinned to 8e549514e3)