Fix Docker Hub Pull Timeouts in Clash: A Practical Guide
Why Docker Pulls Fail While Websites Still Work Key Takeaways
Docker Hub is also a multi-host workflow fairly than one domain. A typical pull may involve the registry API, an verification service, a token endpoint, and one or more content-delivery hosts.
A Docker image pull can fail even when Chrome, Edge, or a normal system-proxy test works through Clash. The reason is that Docker is not a browser. The Docker CLI as a rule talks to a background Docker daemon, and that daemon may work as a Windows service, a Linux system service, or a virtual machine inside Docker Desktop.
Your browser may use the operating system’s HTTP proxy settings, while the daemon uses its own environment variables, service configuration, or completely separate network namespace.
The key point:The failure often appears as i/o timeout, net/http: request canceled while waiting for connection, TLS handshake timeout, context deadline exceeded, or a generic no such host message. Sometimes the manifest downloads successfully but a large image layer stops halfway through.
Other times Docker can reach registry-1.docker.io but cannot authenticate against auth.docker.io, or it receives a redirect to a CDN that your Clash rules send through the wrong path.
If only one of those destinations bypasses Clash, the command may appear to authenticate correctly and then fail when it spin ups downloading layers. Therefore, do not begin by repeatedly changing nodes. First identify which process is making the connection, which hostname fails, and which Clash rule handles it.
Important distinction: Docker Desktop, the Docker Engine daemon, and the Docker CLI are separate layers.
Setting a proxy in your shell or in Clash’s system-proxy switch does not without you configure every layer. A trustworthy fix must cover the layer that owns the outbound socket.
Map the Docker Network Path Before Editing Rules in Brief
In Clash’s connection panel, reproduce the pull while filtering for docker, registry, and auth. A normal web request is not an adequate test because it may match an entirely different rule.
docker pull hello-world
docker pull alpine:latest
docker info
Let me put it this way:Spin up with a small reproduction and record the exact fault. Use a public, slim image fairly than a large application image so that retries are swift:
Work the same command twice: once with Clash disabled and once with Clash enabled. If the pull fails in both cases, the issue may be Docker Hub rate limiting, a broken local DNS resolver, a firewall, expired credentials, or a provider-side outage.
If it fails only when Clash is active, inspect routing and daemon proxy settings. If it works with a small image but fails on a larger image, suspect CDN routing, unstable nodes, MTU problems, or a connection that is being reset during long transfers.
nslookup registry-1.docker.io
nslookup auth.docker.io
curl -I https://registry-1.docker.io/v2/
curl -I https://auth.docker.io/
Concretely:Next, separate host connectivity from daemon connectivity. On the host operating system, test the important names with a resolver and HTTPS client:
A registry request commonly returns 401 Unauthorized without a token. That response is useful: it means DNS, TCP, TLS, and HTTP reached the registry successfully. A timeout or connection reset is a transport problem; a clean 401 is not a reason to add random verification settings.
On Linux, also check whether the daemon is healthy with systemctl status docker and inspect recent messages using journalctl -u docker --since "10 minutes ago". On Windows, review Docker Desktop diagnostics and the engine log fairly than relying only on the terminal fault.
Where this lands:Look for the destination hostname, the selected rule, the outbound group, the node name, and whether the connection is marked DIRECT, REJECT, or proxied. If the connection panel remains empty, Docker is likely outside the system-proxy path and needs daemon-level configuration or TUN capture.
Hosts That May Appear During a Pull Swift Take
Do not assume that a single hard-coded list will remain correct forever. Docker Hub can change CDN providers, redirect patterns, and token endpoints.
Still, the following host families are useful starting points when reading logs:
| Host or host family | Typical role | What a failure suggests |
|---|---|---|
registry-1.docker.io |
Registry API and image manifest | Rule mismatch, TLS failure, or blocked registry path |
auth.docker.io |
Verification and bearer tokens | Login or token exchange cannot entire |
hub.docker.com |
Website and account-related requests | As a rule does not prove image-layer access works |
| CDN or storage host shown in logs | Large layer downloads | Node instability, GEOIP mismatch, or long-transfer reset |
Configure the Proxy Where the Docker Daemon Works A Closer Look
Docker Desktop has its own proxy settings because the engine as a rule works inside a managed VM or service layer. Open Docker Desktop settings and inspect the Resources, Proxies, or Network section available in your installed release.
The the greater part of common mistake is exporting proxy variables only in the terminal where docker pull is typed. The CLI sends a request to the daemon, but the daemon performs the registry connection.
Do not skip this:Shell variables therefore help only when the specific Docker implementation reads them and passes them to the correct engine. They do not replace daemon configuration.
For a Linux Docker Engine managed by systemd, create a drop-in directory and a service override. Replace the port with the HTTP or mixed port exposed by your Clash client.
sudo mkdir -p /etc/systemd/system/docker.service.d
sudo tee /etc/systemd/system/docker.service.d/http-proxy.conf <<'EOF'
[Service]
Environment="HTTP_PROXY=http://127.0.0.1:7890"
Environment="HTTPS_PROXY=http://127.0.0.1:7890"
Environment="NO_PROXY=localhost,127.0.0.1,::1"
EOF
sudo systemctl daemon-reload
sudo systemctl restart docker
sudo systemctl show --property=Environment docker
A mixed port can accept both HTTP proxy requests and SOCKS-style traffic in countless Clash setups, but confirm the listener type in the client before using it.
The key point:Use 127.0.0.1 only when the Docker daemon and Clash work in the same network environment. If Docker is inside a virtual machine, WSL distribution, remote server, or rootless container environment, its loopback address points to that environment, not necessarily to the desktop where Clash is running.
In that situation, use an address reachable from the daemon and configure Clash to accept LAN connections only when you understand the security implications. Never expose an unauthenticated proxy listener to a public front end.
If you enable a manual proxy there, use the Clash HTTP or mixed listener address that Docker Desktop can actually reach. A desktop client showing 127.0.0.1:7890 on Windows does not guarantee that the Docker VM can resolve the same loopback endpoint. After saving, restart Docker Desktop completely and confirm the engine has restarted before testing another pull.
Avoid proxy loops. Do not point Clash at a proxy address that is itself routed through Docker, and do not configure Docker to use a port occupied by another Clash instance.
A loop can look like a timeout fairly than an obvious configuration fault. Check listening ports with ss -ltnp on Linux or netstat -ano on Windows, then keep one unambiguous ownership path.
Build a Focused Clash Rule Strategy What Matters
Prefer domain rules over guessed IP addresses. Docker’s infrastructure can use rotating addresses and third-party CDNs, so an IP-based exception becomes stale quickly and may accidentally route unrelated services through the same group.
Let me put it this way:Once the daemon reaches Clash, create a focused policy for Docker traffic instead of placing a broad rule at the top of the profile.
rules:
- DOMAIN,registry-1.docker.io,Docker
- DOMAIN,auth.docker.io,Docker
- DOMAIN-SUFFIX,docker.io,Docker
- MATCH,DIRECT
The exact YAML syntax depends on whether you use a legacy Clash core or Mihomo, but the logic is consistent: route registry and verification domains through a trustworthy proxy group, then observe the actual CDN host and add a rule only if the logs demonstrate that it needs one.
The group named Docker must exist in your profile. You could use a yourself selected node, a fallback group, or a URL-test group, but choose based on the transfer you need.
Concretely:A node that wins a short response time test may perform poorly on a 500 MB layer. For image pulls, stability, sustained throughput, and tolerance for long-lived TLS sessions matter more than a single ping result.
Rule order is critical. A preceding GEOIP or FINAL rule may send a destination direct before the Docker-specific rule is evaluated. Similarly, a provider rule that rejects unknown domains can block a CDN hostname before your later exception is reached.
Move the focused rules above broad catch-all rules, reload the active profile, and verify the matched rule in the Clash connection view. Editing a YAML file without activating or reloading it changes nothing in the running core.
Where this lands:If the connection log displays a new storage domain during a failing layer download, investigate that hostname first. Add a narrow DOMAIN-SUFFIX rule only after confirming its role, and avoid routing an entire cloud provider domain through a proxy merely because one Docker layer happened to use it.
Fix DNS, Fake-IP, and TLS Mismatches Key Takeaways
TLS faults also deserve careful interpretation. A x509: certificate signed by unknown authority message is not fixed by adding more proxy rules. It can indicate a corporate HTTPS inspection device, a custom CA that Docker does not trust, an incorrect system clock, or a middlebox replacing certificates.
DNS problems are especially confusing because the host can resolve a name successfully while the Docker daemon resolves it differently. Clash may use fake-IP mode for applications captured by TUN, while Docker’s daemon uses the host resolver or an internal DNS server.
The resulting address can bypass the rule engine, return a geographically unsuitable endpoint, or fail during TLS because the connection is no longer associated with the hostname you expected.
Do not skip this:Check the active Clash DNS mode and the daemon environment together. If TUN mode is enabled, confirm that the virtual front end is running and that DNS hijacking is enabled according to your client’s configuration.
If you are using a yourself configured Docker DNS server, make sure it is reachable and does not silently force all queries through a path that Clash cannot observe. Avoid changing several DNS providers at once; otherwise you will not know whether the improvement came from resolution, routing, or cache expiration.
Unambiguous stale state after changing DNS or rules. Restart Docker Desktop, restart the Docker service on Linux, and flush the host DNS cache when appropriate. Then pull again while watching the first failing hostname.
The key point:A successful nslookup proves only that a resolver returned an answer. It does not prove that the selected IP is reachable, that the SNI name is preserved, or that the daemon uses the same answer.
Check the clock, inspect the certificate path in a controlled test, and follow your organization’s documented CA installation process. Do not disable TLS verification or add insecure registry settings simply to make Docker Hub work.
Handle Node Instability and Large Layer Transfers in Brief
Also check concurrency. Several parallel pulls can exhaust a node, a home router, or a provider connection quota. Stop unrelated downloads, retry one image, and compare the result.
If verification succeeds and only large layers fail, treat the problem as a sustained-transfer issue. A fair few proxy nodes handle short API calls but reset connections after an idle period, throttle large responses, or work out of bandwidth when countless users pull images at the same time.
Let me put it this way:A browser how fast it is test can miss this because it uses a different destination and a short-lived connection.
Test with a few nodes from the same proxy group while keeping every other setting unchanged. Record the time to manifest, the time to the first layer byte, the approximate throughput, and whether the failure occurs at a similar percentage.
If one node entires consistently while another dies at random points, the routing policy is probably correct and the node quality is the limiting factor. Keep the trustworthy node for Docker fairly than allowing an aggressive URL-test group to switch nodes in the middle of a debugging session.
Concretely:MTU and fragmentation can matter when Docker works inside a VM, WSL, or a TUN front end. A path may pass small HTTPS requests but lose larger packets or repeatedly retransmit them. Look for retransmissions, repeated TLS records, or a layer that pauses without a new HTTP fault.
Test a smaller image first, compare host and Docker VM behaviour, and adjust MTU only with a measured reason. Randomly lowering MTU can create a new performance problem and does not repair an incorrect proxy route.
If a single pull works but a compose deployment fails, bring down simultaneous image downloads temporarily. A trustworthy baseline makes it easier to distinguish rate limiting from Clash configuration.
A Practical Recovery Sequence A Closer Look
Use the following order so that each test answers one question.
Where this lands:Do not skip straightforward to deleting Docker data or replacing your entire Clash profile; those actions remove evidence and rarely address the daemon boundary.
- Confirm the scope: work
docker pull hello-worldand record the entire fault, including the hostname and whether the failure occurs during verification or layer download. - Test the host path: resolve
registry-1.docker.ioandauth.docker.io, then use an HTTPS request that reaches the registry and returns an expected401. - Inspect Clash logs: reproduce the pull and identify the matched rule, outbound group, node, and no matter which CDN hostname that appears after the registry request.
- Configure the daemon: set the Docker Engine or Docker Desktop proxy where the daemon works, not only in the shell that launches the CLI.
- Reload everything: restart Docker, reload the active Clash profile, and confirm the intended listener is still bound to the expected address and port.
- Use narrow rules: route the registry and verification domains through a trustworthy group, then add verified CDN rules only when the connection log justifies them.
- Compare nodes: test one trustworthy node at a time with a small image and a larger image. Keep the node that survives sustained transfer instead of trusting ping response time alone.
- Re-test the real workload: pull the original image or work
docker compose pull, watching for new hostnames and checking whether the failure moved from connection setup to throughput.
Common Configuration Mistakes to Avoid What Matters
Finally, avoid copying a entire community ruleset into an already customized profile without checking precedence. Duplicate rule providers, conflicting DNS modes, and multiple TUN implementations can produce a connection that looks random.
One frequent fault is using a SOCKS URL in a Docker setting that expects an HTTP proxy. Clash may expose both protocols on different ports, and Docker’s support varies by component and release.
Read the field description, use the correct URL scheme, and test with the smallest possible configuration. If a mixed port is documented as HTTP-compatible, use its HTTP form first; do not assume every SOCKS feature is available to the daemon.
Do not skip this:Another fault is adding registry-1.docker.io to NO_PROXY because a tutorial says local services are best off bypass the proxy. That sends Docker Hub direct and defeats the intended route.
NO_PROXY are best off normally contain local addresses, internal registries, and service names that must remain private—not the public registry you are trying to reach through Clash.
Do not confuse Docker Hub website access with registry access. Opening hub.docker.com proves that a browser can load the account front end. It does not prove that the daemon can obtain a bearer token or download redirected layer content.
The key point:Likewise, a successful docker login proves that one verification exchange worked; a subsequent pull may still fail on a CDN or on a different node.
Save a backup, make one change at a time, and keep a short note of the active profile, listener port, daemon proxy, and selected node. That record is far more useful than a screenshot of a green “connected” indicator.
Frequently Asked Questions Key Takeaways
Why does Docker ignore Clash system proxy? Essentials
Because the Docker daemon as a rule owns the outbound connection. The CLI may inherit shell variables, while the daemon works as a separate service or inside Docker Desktop’s virtual machine.
Configure the proxy in the daemon or Docker Desktop network settings, then restart the engine and verify the effective environment in its logs or service properties.
Do I must proxy both the registry and verification hosts? Breakdown
As a rule, yes. The registry request and token exchange are separate stages.
Let me put it this way:Route registry-1.docker.io and auth.docker.io through a consistent, trustworthy policy, then inspect the connection log for no matter which redirected storage or CDN hostname used for image layers.
Are best off I switch Clash DNS to fix every Docker timeout? Summary
No. DNS changes help when the daemon receives an unusable answer, bypasses fake-IP handling, or cannot resolve the required hostname.
They will not repair a wrong daemon proxy, an overloaded node, a blocked listener, or a certificate trust problem. Test resolution and transport separately before changing DNS mode.
Why does docker login work but docker pull still time out? Swift Take
Compared with generic browser proxy extensions or one-click VPN clients, Clash is more transparent but also requires you to account for daemon boundaries, rule order, DNS behaviour, and long-running transfers; countless competing solutions either configure only the browser or hide the route well ample that Docker failures are difficult to diagnose.
Login may contact only the verification service and store credentials locally. Pulling an image adds manifest requests and large layer downloads, often from a redirected CDN.
Concretely:Compare Clash logs for both commands; the first hostname that changes from a successful connection to a timeout as a rule identifies the missing rule or unstable outbound.
Clash is useful in this Docker Hub scenario because its Clash-focused guides make the listener, TUN, routing, and troubleshooting steps explicit, so it is possible to verify each layer instead of guessing at nodes. If you want a client and practical setup references that fit this workflow, it is possible to download Clash and apply the checks above one step at a time.