How to Fix Docker Build Could Not Resolve Host: A Complete Troubleshooting Guide
We have all been there. You are sipping your morning coffee, you kick off a Docker build, and instead of seeing the satisfying scroll of installed packages, your terminal spits out a frustrating error: Temporary failure resolving 'archive.ubuntu.com' or Could not resolve host: github.com.
Suddenly, your CI/CD pipeline is broken, your local development is halted, and you are left staring at a screen wondering why a tool that literally runs on your machine cannot connect to the internet.
If you are currently stuck trying to figure out how to fix docker build could not resolve host, take a deep breath. This is one of the most common—and easily fixable—networking quirks in containerization. In this comprehensive guide, we are going to dissect why this happens, walk through step-by-step solutions ranging from the most common fixes to bizarre edge cases, and establish preventative measures to keep your builds running smoothly in 2026 and beyond.
Understanding the Root Cause
Before we start firing off commands, we need to understand why Docker is failing to resolve hostnames.
When you run a command like docker build -t my-app ., the Docker CLI sends the build context to the Docker Daemon (the background service actually running your containers). The Daemon processes your Dockerfile line by line. When it hits an instruction like RUN apt-get update or RUN pip install flask, the isolated container environment attempts to reach out to the internet.
To connect to pypi.org or archive.ubuntu.com, the container needs to translate that human-readable domain name into an IP address. It does this by querying a DNS (Domain Name System) server.
The error could not resolve host means one of three things:
1. The container does not know which DNS server to ask. (Missing DNS configuration)
2. The container cannot reach the DNS server. (Network routing issues or firewall blocks)
3. The host machine itself cannot resolve DNS. (A problem outside of Docker)
By default, Docker attempts to configure containers to use the host’s DNS settings, often by reading the host’s /etc/resolv.conf file. However, if the host is using a local DNS resolver (like systemd-resolved which binds to 127.0.0.53), Docker will blindly pass 127.0.0.53 to the container. Inside the container’s isolated network namespace, 127.0.0.53 refers to the container itself, not the host. The container has no DNS server running inside it, so the query fails.
Step-by-Step Solutions (From Most Common to Edge Cases)
Let’s roll up our sleeves and fix this. Work through these solutions in order, as they are organized from the most frequent culprits to the rare edge cases.
Solution 1: Verify Host Machine Connectivity
It sounds obvious, but the first step is to confirm that your host machine actually has internet access and functioning DNS. If your host cannot resolve DNS, Docker doesn’t stand a chance.
Open your terminal on the host machine (not inside Docker) and run:
ping -c 4 google.com
If this fails, your issue is at the operating system level, not Docker. You need to fix your host’s network configuration. However, if the ping succeeds with standard domain names, but Docker still fails, proceed to Step 2.
Solution 2: Explicitly Configure Docker Daemon DNS
This is the magic bullet for 90% of developers facing this issue. We are going to tell the Docker Daemon to bypass the host’s /etc/resolv.conf and explicitly use reliable public DNS servers (like Google’s 8.8.8.8 or Cloudflare’s 1.1.1.1) for all containers and builds.
To do this, you need to edit or create the Docker Daemon configuration file, usually located at /etc/docker/daemon.json.
Open it with your favorite text editor:
sudo nano /etc/docker/daemon.json
Add the following JSON configuration. If the file already has content, just carefully merge the "dns" key into the existing JSON object.
{
"dns": ["8.8.8.8", "8.8.4.4", "1.1.1.1"]
}
Save the file and exit. For these changes to take effect, you must restart the Docker Daemon:
sudo systemctl restart docker
Now, try running your docker build command again. By explicitly defining public DNS servers at the daemon level, any container spawned during the build process will use these IP addresses to resolve hostnames, entirely bypassing the 127.0.0.x local loopback issue.
Solution 3: Use the Host Network During Build
If you do not have administrative access to modify /etc/docker/daemon.json (for instance, you are a developer working on a strict corporate workstation or using a shared CI runner), you can bypass the issue during the specific build using the host’s network stack.
Docker builds have a --network flag. By default, they use a isolated bridge network. You can tell the build to share the host’s network namespace directly:
docker build --network=host -t my-app .
When you pass --network=host, the building container shares the host’s exact network interfaces, routing tables, and DNS configuration (/etc/resolv.conf).
A word of caution: While this is a fantastic quick fix, it sacrifices container isolation. It means the build process has direct access to your host’s network, which can occasionally lead to port binding conflicts during the build. Use it for debugging and building, but avoid making it a permanent crutch in production Dockerfiles.
Solution 4: Injecting DNS into the Dockerfile
Sometimes you need a portable fix that travels with the codebase. You can actually modify the resolv.conf file inside the container during the build process using a RUN instruction in your Dockerfile.
Note: Modifying system files in the Dockerfile is generally considered an anti-pattern because it ties your Dockerfile to specific OS-level implementations. However, when you are in a bind, it works flawlessly.
Here is how you can do it in an Ubuntu/Debian-based Dockerfile:
FROM ubuntu:24.04
# Fix DNS resolution issues during build
RUN echo "nameserver 8.8.8.8" > /etc/resolv.conf && \
echo "nameserver 8.8.4.4" >> /etc/resolv.conf
# Now run your package installations
RUN apt-get update && apt-get install -y curl python3
This approach explicitly overwrites the container’s DNS configuration before it attempts to download any packages or dependencies.
Solution 5: VPN and Corporate Proxy Interference
If you are working remotely or in an enterprise environment, a VPN or Proxy is often the silent saboteur of Docker DNS.
When you connect to a corporate VPN, the VPN client often rewrites the host’s /etc/resolv.conf to point to the corporate DNS server. However, Docker’s networking bridge (docker0) might not be routing traffic through the VPN interface. The container tries to reach the corporate DNS server but hits a network wall.
The Fix:
1. Check your routes: Ensure traffic from the Docker bridge is allowed through your VPN interface.
2. Pass Proxy Variables: If your company uses a proxy for internet access, Docker won’t magically know about it. You need to pass proxy variables during the build.
You can pass build arguments for proxies like this:
docker build \
--build-arg HTTP_PROXY="http://proxy.mycompany.com:8080" \
--build-arg HTTPS_PROXY="http://proxy.mycompany.com:8080" \
--build-arg NO_PROXY="localhost,127.0.0.1" \
-t my-app .
If you are tired of typing that out, you can configure the Docker Daemon to use proxies globally by creating a drop-in configuration directory:
sudo mkdir -p /etc/systemd/system/docker.service.d
sudo nano /etc/systemd/system/docker.service.d/http-proxy.conf
Add the following:
[Service]
Environment="HTTP_PROXY=http://proxy.mycompany.com:8080"
Environment="HTTPS_PROXY=http://proxy.mycompany.com:8080"
Environment="NO_PROXY=localhost,127.0.0.1"
Then reload systemd and restart Docker:
sudo systemctl daemon-reload
sudo systemctl restart docker
Solution 6: Docker Desktop and WSL2 Quirks (Windows)
For developers using Docker Desktop on Windows with the WSL2 backend, networking is an entirely different beast. Docker Desktop runs inside a highly optimized utility VM inside WSL2.
In this environment, the DNS resolution chain is: Container -> Docker Desktop VM -> Windows Host -> Windows DNS. If there is a breakdown between the WSL2 VM and the Windows host, you will get the “could not resolve host” error.
The Fix:
Often, the fastest fix for WSL2 DNS issues is to create or edit a wsl.config file on your Windows host.
Open PowerShell and edit the file:
notepad $env:USERPROFILE\.wslconfig
Add the following to force WSL to mirror the host’s networking correctly (note: networking mirroring features were significantly enhanced in recent WSL updates):
[wsl2]
networkingMode=mirrored
After saving, shut down WSL completely and restart Docker Desktop:
wsl --shutdown
Restart Docker Desktop and attempt your build again. Mirrored networking mode ensures that the WSL2 VM shares the exact same network interfaces and DNS capabilities as the Windows host, clearing up the routing issues.
Solution 7: MTU (Maximum Transmission Unit) Mismatches
This is a rare, frustrating edge case. Every network interface has an MTU value, which is the largest size packet it will transmit. By default, Ethernet networks use an MTU of 1500. Docker networks also default to 1500.
However, if your host network (especially VPNs or cloud providers like AWS with jumbo frames) has a different MTU, packets can get silently dropped. DNS requests typically use tiny UDP packets, so they usually survive. But if the DNS response is large enough to require fragmentation and the MTU is misconfigured, the response never reaches the container.
This often manifests as DNS working for simple pings but failing during complex apt-get update requests or when resolving domains with many records.
The Fix:
Check your host’s MTU:
ip link | grep mtu
If your host has an MTU of, say, 9000 (Jumbo frames) or 1400 (common on VPNs), Docker might be struggling. You can tell Docker to match the MTU during the build, or globally in daemon.json.
To set it globally, open /etc/docker/daemon.json:
{
"mtu": 1400,
"dns": ["8.8.8.8"]
}
Restart the daemon:
sudo systemctl restart docker
This ensures Docker containers construct packets that are small enough to pass through your host’s network without fragmentation issues.
Advanced Troubleshooting Tools
If you have tried all the above and the error persists, it’s time to put on your detective hat and use some low-level networking tools to debug the container.
Inspecting BuildKit DNS
In modern Docker versions (Docker Engine v25+ as of 2026), BuildKit is the default builder. You can actually SSH into the BuildKit build environment to poke