Kubernetes Image Pull "dial tcp i/o timeout" to Registry - Fix in CI
By Kaveh Alemi·Latchkey
The kubelet tried to reach the registry to pull an image and the TCP connection timed out. The reference and credentials are fine - the node could not establish a connection in time, usually a transient network/egress blip that succeeds on the kubelet’s retry.
What this error means
Pod events show Failed to pull image "..." : ... dial tcp <ip>:443: i/o timeout, then a retry. It is intermittent - some pulls on the same node succeed, and re-pulling the image generally works.
A momentary loss of egress (NAT gateway hiccup, route flap) keeps the node from reaching the registry within the timeout. The next attempt usually connects.
Registry slow or overloaded
A registry that is briefly slow to accept connections causes the dial to time out; it recovers as load eases.
How to fix it
Confirm it is transient and let the kubelet retry
Watch the events - the kubelet re-pulls on a back-off. A retry succeeding confirms a network blip, not a config error.
Terminal
kubectl get events --field-selector involvedObject.name=<pod> --watch
kubectl describe pod <pod> | grep -A2 -i 'i/o timeout'
Reduce dependence on a flaky path
Serve images from an in-region registry or pull-through cache to shorten the network path.
Pre-pull hot images onto nodes (DaemonSet) so per-pod pulls are rare.
Ensure node egress (NAT/route) is reliable and not saturated.
How to prevent it
Use a nearby/internal registry or pull-through cache to cut transfer distance.
Pre-pull and pin digests so cached layers are reused across nodes.
Keep node egress capacity healthy so transient timeouts are rare.
Frequently asked questions
What causes "image pull "i/o timeout""?
A momentary loss of egress (NAT gateway hiccup, route flap) keeps the node from reaching the registry within the timeout. The next attempt usually connects.
How do I fix image pull "i/o timeout"?
Watch the events - the kubelet re-pulls on a back-off. A retry succeeding confirms a network blip, not a config error.
Can Latchkey fix this automatically?
Yes. Latchkey runs your GitHub Actions on managed runners that detect this failure, apply the fix, and retry the job automatically - self-healing is on by default.