What happens
When the liveness check port is 443 with TLS enabled, buildLivenessUri strips the port suffix:
if ((tlsEnabled && 443 == livenessCheckPort) || (!tlsEnabled && 80 == livenessCheckPort)) {
portSuffix = "";
} else {
portSuffix = ":" + livenessCheckPort;
}
(core/src/main/java/org/testcontainers/containers/wait/strategy/HttpWaitStrategy.java, confirmed on main; first observed on 1.21.4.)
That elision is only correct when the probe target is literally the default-port endpoint. With a mapped/dynamic port setup — e.g. .withExposedService("nlb", 443, Wait.forHttp("/health").forPort(443)) where 443 maps to a random host port, or any case where the resolved check port is 443 but the service is not at https://host/ — the probe becomes https://<host>/path instead of https://<host>:<port>/path and silently checks the wrong endpoint (the host's real 443, often connection-refused or a different server entirely).
Why it matters
The failure mode is silent misdirection: the wait times out with Timed out waiting for URL to be accessible, and nothing in the message reveals the port was dropped. We lost about an hour to this before reading buildLivenessUri — the natural suspicion is TLS certificates or the service itself, not URI construction.
Suggestion
Only elide the port when the resolved URI host+port is genuinely the default endpoint, or log the full probe URI at info level (it is logged — but only after construction, so a reader must already suspect the URI to look). At minimum, documenting that .forPort(443)/.forPort(80) are effectively ignored would save the next person the hour.
Happy to shape this into a PR if a maintainer confirms the intended behavior.
What happens
When the liveness check port is 443 with TLS enabled,
buildLivenessUristrips the port suffix:(
core/src/main/java/org/testcontainers/containers/wait/strategy/HttpWaitStrategy.java, confirmed onmain; first observed on 1.21.4.)That elision is only correct when the probe target is literally the default-port endpoint. With a mapped/dynamic port setup — e.g.
.withExposedService("nlb", 443, Wait.forHttp("/health").forPort(443))where 443 maps to a random host port, or any case where the resolved check port is 443 but the service is not athttps://host/— the probe becomeshttps://<host>/pathinstead ofhttps://<host>:<port>/pathand silently checks the wrong endpoint (the host's real 443, often connection-refused or a different server entirely).Why it matters
The failure mode is silent misdirection: the wait times out with
Timed out waiting for URL to be accessible, and nothing in the message reveals the port was dropped. We lost about an hour to this before readingbuildLivenessUri— the natural suspicion is TLS certificates or the service itself, not URI construction.Suggestion
Only elide the port when the resolved URI host+port is genuinely the default endpoint, or log the full probe URI at info level (it is logged — but only after construction, so a reader must already suspect the URI to look). At minimum, documenting that
.forPort(443)/.forPort(80)are effectively ignored would save the next person the hour.Happy to shape this into a PR if a maintainer confirms the intended behavior.