curl: (6) Could Not Resolve Host — The Three DNS Layers

Name resolution failed before any connection attempt. Either the name is wrong, the resolver is unreachable, or the record genuinely doesn't exist (anymore). dig against different resolvers isolates which layer failed.

What you'll see

Root causes

Typo, scheme artifact, or nonexistent record

A stray space, a missing quote, or a URL fragment curl treats as a second host. Also genuinely-dead domains. dig +short <host> from a known-good resolver (1.1.1.1) answers existence.

Local resolver broken or unreachable

Bad /etc/resolv.conf, a dead VPN's DNS push, or a container with a missing/misconfigured resolver. dig @1.1.1.1 <host> succeeding while plain dig fails = local resolver problem, not the domain.

Split-horizon / internal-only names

An internal hostname resolves via the corporate resolver but not public DNS: works in the office, fails from CI or a container using 8.8.8.8. The name exists only inside one view.

Fix it

  1. Test the name against known-good resolvers
    dig +short <host> ; dig +short <host> @1.1.1.1 ; echo 'nameserver' etc: cat /etc/resolv.conf
  2. Local resolver broken: point somewhere sane temporarily
    printf 'nameserver 1.1.1.1\nnameserver 8.8.8.8\n' | sudo tee /etc/resolv.conf   # then fix the underlying resolver (DHCP/VPN/Docker)
  3. Containers: match the host's DNS or specify it
    docker run --dns 1.1.1.1 ...   # or compose: dns: [1.1.1.1] — check the network's embedded DNS first
  4. Verify curl is being fed the exact host you think
    curl -v <url> 2>&1 | grep -i 'trying\|resolve'   # the -v output shows the exact name attempted

Field note

Error 6 (resolve) vs 7 (refused) vs 28 (timeout) is the whole diagnostic: 6 means DNS, full stop — no port, firewall, or service debugging applies until it's fixed. The resolv.conf in containers is often a Docker-generated stub pointing at the embedded resolver (127.0.0.11) — overriding it bypasses container DNS names. Use --dns carefully.

Common questions

Why does it work in my browser but not in curl?

Browser DNS-over-HTTPS or cached entries succeed where the system resolver fails. dig from the same machine reproduces the curl view and confirms the resolver layer, not the site.

My container suddenly can't resolve after a restart. Why?

The embedded Docker resolver forwards to the host's DNS: if the host's resolv.conf changed (VPN toggled, network switched), containers inherit the breakage. Fix the host resolver, restart the container.

Ship it right the first time

Our most-documented failures, packaged as ready-to-ship starter kits: Docker, Kubernetes, and Terraform.

Browse the template store →

One-time. Yours to modify. Instant download from the NinjaOps template store.