testcontainers/testcontainers-java · error · IllegalStateException

Maximum number of proxies exceeded

Error message

Maximum number of proxies exceeded

What it means

ToxiproxyContainer allocates one container port per proxy from a fixed range (nextPort counter up to LAST_PROXIED_PORT). When more distinct upstreams are requested than ports in the range, getProxy throws this IllegalStateException.

Solutions

  1. Reduce the number of distinct upstreams proxied through the single Toxiproxy container.
  2. Create additional ToxiproxyContainer instances and distribute upstreams among them.
  3. Reuse one ContainerProxy per upstream (getProxy already caches by upstream) instead of expecting unlimited slots.
  4. Build the container with a larger port range if supported by your testcontainers version, or bump to a version with a wider default range.

Example fix

// before
for (HostAndPort upstream : fiftyUpstreams) {
    container.getProxy(upstream); // exhausts port range
}
// after
// spread across two containers
ToxiproxyContainer c1 = new ToxiproxyContainer("ghcr.io/shopify/toxiproxy:2.11.0");
ToxiproxyContainer c2 = new ToxiproxyContainer("ghcr.io/shopify/toxiproxy:2.11.0");
for (int i = 0; i < fiftyUpstreams.size(); i++) {
    (i < 25 ? c1 : c2).getProxy(fiftyUpstreams.get(i));
}
Defensive patterns

Strategy: fallback

Validate before calling

if (distinctUpstreams.size() > 20) {
    throw new IllegalArgumentException("too many upstreams for one ToxiproxyContainer; split across containers");
}

Try / catch

try { proxy = toxiproxy.getProxy(upstream); } catch (IllegalStateException e) { if (e.getMessage().contains("Maximum number of proxies exceeded")) { toxiproxy2.start(); proxy = toxiproxy2.getProxy(upstream); } else throw e; }

Prevention

When it happens

Trigger: Calling getProxy(new HostAndPort(...)) for more unique upstreams than the pre-allocated port range allows (containers created without extra exposed ports / with fewer than needed proxy slots).

Common situations: Large test topologies proxying many backing services through one Toxiproxy container; creating multiple proxies for the same test class without reusing the container's proxy slots.

Understand the failure class

Background: "value must be between 0 and 1" / "out of range" / "must not be negative" errors: fixing range-validation failures across open-source libraries — this error's family across 42 libraries.

Related errors


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

Appendix: source

Thrown at modules/toxiproxy/src/main/java/org/testcontainers/containers/ToxiproxyContainer.java:130

     * useful in most scenarios, but this method is present to allow use of Toxiproxy in front of containers
     * or external servers that are not managed by Testcontainers.</em></p>
     *
     * @param hostname hostname of target server to be proxied
     * @param port port number on the target server that should be proxied
     * @return a {@link ContainerProxy} instance
     * @deprecated {@link ToxiproxyContainer} will not build the client. Proxies should be provided manually.
     */
    @Deprecated
    public ContainerProxy getProxy(String hostname, int port) {
        String upstream = hostname + ":" + port;

        return proxies.computeIfAbsent(
            upstream,
            __ -> {
                try {
                    final int toxiPort = nextPort.getAndIncrement();
                    if (toxiPort > LAST_PROXIED_PORT) {
                        throw new IllegalStateException("Maximum number of proxies exceeded");
                    }

                    final Proxy proxy = client.createProxy(upstream, "0.0.0.0:" + toxiPort, upstream);
                    final int mappedPort = getMappedPort(toxiPort);
                    return new ContainerProxy(proxy, getHost(), mappedPort, toxiPort);
                } catch (IOException e) {
                    throw new RuntimeException("Proxy could not be created", e);
                }
            }
        );
    }

    @RequiredArgsConstructor(access = AccessLevel.PROTECTED)
    @Deprecated
    public static class ContainerProxy {

        private static final String CUT_CONNECTION_DOWNSTREAM = "CUT_CONNECTION_DOWNSTREAM";

View on GitHub (pinned to 8e549514e3)