curl Error: '(6) Could not resolve host' — Cause, Fix, and Troubleshooting Guide
Fix curl: (6) Could not resolve host: api.example.com — DNS resolution failures from typos, broken resolv.conf, VPN/split-horizon names, and container DNS.
- #automation
- #troubleshooting
- #curl
Fixing errors like this? Get 500 free DevOps AI prompts
500 copy-paste AI prompts for the stack you actually run — one PDF, free.
Overview
curl exit code 6 is a name-resolution failure: curl asked the resolver to turn a hostname into an IP address and got nothing back. It never opened a socket — this happens before any TCP connection, so it is purely a DNS problem, not a firewall or service problem.
$ curl -v https://api.example.com/health
* Could not resolve host: api.example.com
* Closing connection
curl: (6) Could not resolve host: api.example.com
The distinction matters for triage: code 6 means “I don’t know where that name points,” which is different from code 7 (“I know the address but can’t connect”) and code 28 (“I tried but timed out”). The fix lives in DNS configuration, /etc/hosts, the resolver, or the name itself — never in the target service.
Symptoms
- curl exits with
curl: (6) Could not resolve host: <name>. - The failure is near-instant, with no
Trying <ip>...line — because curl never got an IP to try. getent hosts <name>returns nothing.- Resolving by IP works but resolving by name fails.
- The name resolves on your laptop but not inside a container, CI runner, or a host off the VPN.
curl -sS -o /dev/null -w '%{http_code}\n' https://api.example.com/health; echo "exit: $?"
exit: 6
Common Root Causes
1. Typo in the hostname
The simplest and most common: api.exmaple.com, a trailing space, or a copy-paste that dropped a character.
2. No working DNS / broken resolv.conf
The resolver is empty, points at an unreachable server, or was overwritten.
cat /etc/resolv.conf
# (empty)
3. Internal name that only resolves on the VPN or inside the cluster
Split-horizon DNS: api.internal.example.com resolves on the corporate network or inside Kubernetes, but not from a public host or a disconnected VPN.
4. Missing /etc/hosts entry for a name that has no DNS record
A name that is only defined in /etc/hosts (or was expected to be) fails everywhere the entry is absent.
5. Container / pod DNS misconfiguration
A container with the wrong --dns, a broken resolv.conf mounted from the host, or CoreDNS not reachable from the pod.
6. Proxy expected to do resolution
In some corporate setups the name only resolves through an HTTP proxy; curl bypassing the proxy cannot resolve it directly.
How to Diagnose
Step 1: Confirm it is DNS, isolated from curl
getent hosts api.example.com || echo "no resolution"
no resolution
getent uses the same NSS path as most programs; an empty result confirms a resolver-level failure.
Step 2: Query DNS directly
dig +short api.example.com
nslookup api.example.com
;; connection timed out; no servers could be reached
An empty answer means no record; “no servers could be reached” means the resolver itself is broken.
Step 3: Inspect the resolver configuration
cat /etc/resolv.conf
nameserver 10.0.0.2
search svc.cluster.local
An empty file, a 127.0.0.53 stub with no upstream, or a wrong nameserver all break resolution.
Step 4: Test with a known-good resolver
dig @1.1.1.1 +short api.example.com
If a public resolver answers but your configured one does not, the fault is your resolver, not the record. If neither answers, the record does not exist publicly (likely an internal/VPN name).
Step 5: Check basic network reachability
ping -c1 1.1.1.1
No route to a public IP means the box has no network at all, which also breaks DNS.
Fixes
Correct an obvious typo and retry:
curl -v https://api.example.com/health
Repair the resolver. On a systemd-resolved host:
sudo systemctl restart systemd-resolved
resolvectl status | head
Or set a working nameserver directly (for a host not managed by resolved):
# /etc/resolv.conf
nameserver 10.0.0.2
nameserver 1.1.1.1
For an internal name, connect the VPN or run from inside the cluster; verify with getent hosts. As a temporary override, add an /etc/hosts entry:
echo "10.0.5.40 api.example.com" | sudo tee -a /etc/hosts
getent hosts api.example.com
10.0.5.40 api.example.com
For containers, set a reachable DNS server:
docker run --dns 10.0.0.2 myimage curl -sS https://api.example.com/health
In Kubernetes, confirm CoreDNS is healthy and the pod’s resolv.conf points at the cluster DNS service.
What to Watch Out For
- Code 6 is strictly DNS — do not open firewall tickets or restart the target service; neither is the cause.
searchdomains inresolv.confcan make a short name resolve while the FQDN fails (or vice-versa); test the exact string curl uses.- A stale
/etc/hostsoverride outlives the outage it was meant to patch and later sends traffic to a dead IP — remove temporary entries. - Split-horizon names look “broken” from the wrong network but are working as designed; check whether the name is supposed to be internal.
- Containers inherit DNS from the host or the runtime, not your shell — debug resolution inside the container.
Related Guides
- curl (7) Failed to connect after N ms: Connection refused
- curl (28) Operation timed out
- connect ECONNREFUSED — webhook target connection refused
Get 500 Battle-Tested DevOps AI Prompts — Free
500 battle-tested, copy-paste AI prompts engineered by a senior systems engineer — every one with fill-in placeholders and safety/back-out notes. Drop your email and it's yours.
- 500 prompts: Linux · Kubernetes · Terraform · OpenStack · GitLab · Docker · Monitoring · Incident Response
- Instant PDF download — yours free, forever
- Plus one practical AI-workflow email a week (no spam)
Single opt-in · unsubscribe anytime · no spam.