Cloud Native 7 min read

Why Docker Containers Time Out on HTTPS: MTU Misconfiguration and How to Fix It

When running Jenkins inside a Docker container on a VM, HTTPS requests to accounts.google.com time out due to an MTU mismatch between the host and the container, which can be resolved by adjusting the MSS via iptables or setting a lower MTU for Docker interfaces.

Efficient Ops
Efficient Ops
Efficient Ops
Why Docker Containers Time Out on HTTPS: MTU Misconfiguration and How to Fix It

Story Origin

We needed to set up Jenkins, a Java application, on a new environment. To avoid maintaining a Java runtime ourselves, we decided to run Jenkins inside Docker. After provisioning a VM, installing Docker, and launching the official Jenkins Docker image, the Jenkins UI reported an error.

The Jenkins log showed a java.net.SocketTimeoutException: Read timed out , but it was unclear which service caused the timeout.

Collecting Information

Using

tcpdump

during Jenkins startup, we discovered that connections to a specific IP on port 443 were hanging, even though the IP was reachable via ping, indicating a problem above layer 3.

Further DNS capture revealed that the IP corresponded to accounts.google.com . Inside the container we could ping the domain and successfully

curl http://accounts.google.com

, but

curl https://accounts.google.com

always timed out. Other HTTPS sites were reachable, albeit slowly.

On the VM host,

curl https://accounts.google.com

worked fine, confirming that the host network was healthy.

Answer

Reviewing Docker’s networking model shows the packet path:

container eth0 → host veth → docker0 bridge → host eth0 → WAN

. Since the host network works, the issue lies between the container and the host bridge.

Packet captures showed that after the TCP handshake, HTTP traffic flowed normally, but HTTPS traffic stalled. The packets returning from port 443 had a length of 0, suggesting they were dropped due to an oversized MTU.

Because the host’s MTU is 1450 while Docker defaults to 1500, the extra encapsulation added by the overlay network exceeds the MTU, causing fragmentation or loss of TLS packets.

Proof

The mismatch in MTU leads to incorrect TCP MSS negotiation. The host’s MTU is 1450, but Docker’s default is 1500. When the container assumes an MTU of 1500, packets larger than the allowed size are dropped, resulting in the observed HTTPS timeout.

Solution

Two practical fixes are available:

Use MSS clamping with

iptables

to force the TCP handshake MSS to a safe value (e.g., 1410):

<code>iptables -I FORWARD -p tcp -m tcp --tcp-flags SYN,RST SYN -j TCPMSS --set-mss 1410</code>

Specify a lower MTU for Docker’s default bridge when starting the daemon:

<code>dockerd --default-network-opt=bridge=com.docker.network.driver.mtu=1234</code>

After applying either fix, HTTPS requests from the Docker container succeed.

DockernetworkingHTTPSiptablesMSSMTU
Efficient Ops
Written by

Efficient Ops

This public account is maintained by Xiaotianguo and friends, regularly publishing widely-read original technical articles. We focus on operations transformation and accompany you throughout your operations career, growing together happily.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.