Docker

How to Fix "DNS lookup failed inside Docker container"

3 min read by DebuggedIt

Quick answer

The "DNS lookup failed inside Docker container" issue occurs when containers cannot resolve external domain names or internal container hostnames through...

The "DNS lookup failed inside Docker container" issue occurs when containers cannot resolve external domain names or internal container hostnames through network name resolution. When a container attempts to make outbound HTTP requests, fetch packages, or connect to external APIs, requests time out with domain name resolution exceptions. This typically stems from mismatches between host system resolution daemons (like systemd-resolved) and Docker's embedded DNS engine.

The Problem

Running commands inside a container that rely on domain resolution (such as curl, apt-get, or ping) fail continuously with name resolution errors:

$ docker run --rm alpine ping google.com
ping: bad address 'google.com'

In application runtimes (such as Node.js or Python), error traces highlight DNS lookup failures explicitly:

Error: getaddrinfo ENOTFOUND api.github.com
    at GetAddrInfoReqWrap.onlookup [as oncomplete] (node:dns:107:26) {
  errno: -3008,
  code: 'ENOTFOUND',
  syscall: 'getaddrinfo',
  hostname: 'api.github.com'
}
urllib3.exceptions.MaxRetryError: HTTPSConnectionPool(host='api.stripe.com', port=443): Failed to establish a new connection: [Gaierror -3] Temporary failure in name resolution

Why It Happens

Docker containers use an embedded DNS server located at local IP 127.0.0.11. When a container queries external hostnames, 127.0.0.11 forwards the request to the nameservers listed in the host's /etc/resolv.conf file. Common breakdown causes include:

  • Systemd-resolved Loopback Addresses: Modern Linux distributions (Ubuntu/Debian) use 127.0.0.53 in host /etc/resolv.conf. Docker ignores local loopback addresses to prevent routing loops, defaulting to fallback Google DNS (8.8.8.8/8.8.4.4), which may be blocked on corporate firewalls.
  • VPN Network Overrides: Corporate VPN software alters host DNS configurations, causing container DNS requests routed to external resolvers to fail.
  • Custom Bridge Subnet Conflicts: Custom Docker networks overlap with local physical network subnets, blocking routing to local DNS servers.

The Fix

Configure Docker globally to use reliable public or local upstream DNS servers explicitly.

Step 1: Set global DNS servers in daemon.json

Edit or create the Docker daemon configuration file at /etc/docker/daemon.json on your Linux host:

sudo nano /etc/docker/daemon.json

Add explicit upstream DNS servers (such as Google DNS 8.8.8.8 and Cloudflare DNS 1.1.1.1, or your corporate internal DNS IP addresses):

{
  "dns": ["8.8.8.8", "1.1.1.1"]
}

Save the file and restart the Docker daemon:

sudo systemctl restart docker

Step 2: Configure custom DNS per container or Compose service

If you prefer setting DNS per service without changing global settings, specify the dns array in docker-compose.yml:

version: '3.8'
services:
  app:
    image: node:20-alpine
    dns:
      - 8.8.8.8
      - 1.1.1.1
    command: node index.js

Or using the Docker CLI:

docker run --rm --dns 8.8.8.8 alpine ping google.com

Step 3: Fix host systemd-resolved integration

If running Ubuntu, point Docker to the actual upstream NetworkManager/systemd-resolved file rather than the local stub file by creating a symlink or overriding options:

sudo ln -sf /run/systemd/resolve/resolv.conf /etc/resolv.conf
sudo systemctl restart docker

Still Not Working?

If DNS resolution continues to fail on Linux host environments, check your host's iptables firewall rules. Security tools like ufw or firewalld often block forwarding from Docker bridge interfaces (docker0) to the primary network interface.

Allow forwarding traffic in ufw:

sudo ufw default allow routed
sudo ufw reload

Verify DNS resolution inside a fresh container:

docker run --rm alpine nslookup google.com