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
Stuck on this Automation error? Get the free incident triage checklist
A one-page PDF — the exact steps to isolate, fix, and verify a production error like this one. No spam, unsubscribe anytime.
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
Fixed it? Get 500 Automation & 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.
Stuck on this? Start guided troubleshooting
Open an interactive diagnostic session with this error already loaded. Work a step-by-step plan, record what each check returns, land on a root cause, and export a clean incident summary — no account needed to start.
Did this fix your issue?
Solved it a different way?
Share the fix that worked for you — reviewed, then published to help the next engineer.
That looks like it may contain a secret (key, token, password, or connection string). Please remove it — a note with a detected secret can’t be published.
Thanks — that helps. Published notes appear after a quick review.
Trending errors this week
The error guides other engineers are actually reading right now.
- 1mount: wrong fs type, bad option, bad superblock
- 2Docker 'failed to set up container networking': Fix the Bridge and IP Pool
- 3Docker 'failed to create shim task': How to Fix the containerd Runtime Error
- 4Transport endpoint is not connected
- 5modprobe: FATAL: Module not found
- 6mount: wrong fs type, bad option, bad superblock
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.