Prometheus Error Guide: 'dial tcp: i/o timeout' — Fix Scrape Timeouts
Fix Prometheus scrape 'i/o timeout' errors: diagnose slow targets, firewall drops, DNS latency, and scrape_timeout tuning so targets stop flapping and stay UP.
- #prometheus
- #monitoring
- #troubleshooting
- #errors
Stuck on this Prometheus & Monitoring 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
Prometheus marks a target DOWN and records this error on the target’s status page whenever a scrape cannot complete a TCP read or connect within the allotted time:
Get "http://10.0.0.5:9100/metrics": dial tcp 10.0.0.5:9100: i/o timeout
The same class of failure also appears mid-transfer, after the connection is established but the body never fully arrives:
Get "http://10.0.0.5:9100/metrics": context deadline exceeded (Client.Timeout exceeded while awaiting headers)
Both mean the scrape did not finish within scrape_timeout. The target may be reachable but slow, or the network path may be silently dropping packets. Until it resolves, up{} for that target is 0 and every alert and dashboard built on those metrics goes blind.
Symptoms
- The target shows
DOWNin Status → Targets with adial tcp ...: i/o timeouterror. up{job="..."} == 0for the affected instance, often flapping between 0 and 1.- Scrape duration for the target sits near or above
scrape_timeoutright before it fails. - Other targets on the same host or subnet may fail together (shared network path).
- Manual
curlof/metricsfrom the Prometheus host is slow or hangs.
Common Root Causes
- The target is genuinely slow — the exporter takes longer than
scrape_timeoutto render/metrics(huge cardinality, expensive collectors, or a blocked backend). - Firewall / security group drops — packets are silently dropped (not rejected), so the connection hangs until timeout instead of failing fast.
- DNS resolution latency — a slow resolver delays the
dialphase, eating the timeout budget before bytes flow. - Network saturation or packet loss on the path between Prometheus and the target.
scrape_timeouttoo low for a legitimately large payload, especially node_exporter with many collectors or kube-state-metrics on big clusters.- Target overloaded — CPU-starved exporter cannot serve the request in time.
Diagnostic Workflow
Start by reproducing the scrape from the Prometheus host to separate “target slow” from “network broken”:
time curl -sS -o /dev/null -w '%{http_code} %{time_total}s\n' \
http://10.0.0.5:9100/metrics
If that hangs, test raw connectivity and DNS independently:
nc -vz -w 5 10.0.0.5 9100 # TCP reachability
dig +short exporter.internal # is DNS itself slow/failing?
mtr -rwc 20 10.0.0.5 # packet loss / latency along the path
Check how close scrapes run to the timeout using Prometheus’s own meta-metrics:
scrape_duration_seconds{job="node"}
/ on(job) group_left() scrape_timeout_seconds
Confirm the configured budget in the job:
scrape_configs:
- job_name: node
scrape_interval: 30s
scrape_timeout: 10s # must be <= scrape_interval
static_configs:
- targets: ["10.0.0.5:9100"]
If the exporter itself is the bottleneck, measure how long it takes to render, and how big the payload is:
curl -sS http://10.0.0.5:9100/metrics | wc -l
Example Root Cause Analysis
A node_exporter fleet started flapping after a systemd rollout added hundreds of units per host. curl of /metrics returned HTTP 200 but took 11.4s; scrape_timeout was 10s. The mtr path was clean with 0% loss, so the network was ruled out. The systemd collector was enumerating thousands of units, and rendering exceeded the budget.
The fix was two-fold: restrict the systemd collector to a unit allowlist (--collector.systemd.unit-include) to cut render time to 1.2s, and raise scrape_timeout to 15s on that job as headroom. up{} returned to a stable 1 and scrape_duration_seconds dropped well below the timeout.
Prevention Best Practices
- Keep
scrape_timeoutcomfortably belowscrape_interval, and size it against the target’s real p99 render time plus network margin. - Alert on
scrape_duration_seconds / scrape_timeoutcrossing ~0.8 so you catch creeping slowness before targets flap. - Prefer
rejectover silentdropin firewalls for monitored ports so failures are fast and diagnosable. - Trim expensive exporter collectors and high-cardinality endpoints rather than endlessly raising timeouts.
- Alert on
up == 0grouped by target, and separately on flapping (changes(up[15m]) > 3).
Quick Command Reference
# Reproduce the scrape with timing
time curl -sS -o /dev/null -w '%{time_total}s\n' http://TARGET:PORT/metrics
# Raw TCP + DNS + path checks
nc -vz -w 5 TARGET PORT
dig +short TARGET_HOST
mtr -rwc 20 TARGET
# Payload size (proxy for render cost)
curl -sS http://TARGET:PORT/metrics | wc -l
up == 0
scrape_duration_seconds
changes(up[15m]) > 3
Conclusion
dial tcp: i/o timeout is Prometheus telling you a scrape ran out of time — either the target is too slow or the network path is dropping traffic. Reproduce with a timed curl, split network from target with nc/mtr, then either fix the slow exporter (trim collectors, reduce cardinality) or grant realistic scrape_timeout headroom. Alerting on scrape duration relative to the timeout turns this from a recurring flap into an early warning.
Fixed it? Get 500 Prometheus & Monitoring & 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.
Did this fix your issue?
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.