What it means: curl gave up because a time limit expired before the request finished.
curl -wFree online tool — ping & port checker: instant results, no signup.
Pings your host from our server, so you see whether it answers from outside your network.
Exit code 28 is libcurl's CURLE_OPERATION_TIMEDOUT, documented as «Operation timeout. The specified time-out period was reached according to the conditions» (libcurl error codes). curl did not get an error from the network; a timer ran out. Which timer, and in which phase, is in the message after the code. In the curl source (lib/multi.c) the texts are:
Resolving timed out after N milliseconds — the DNS lookup never finished.Connection timed out after N milliseconds — the name resolved, but the TCP (and TLS) handshake did not complete in time.Operation timed out after N milliseconds with X out of Y bytes received (or with X bytes received when the size is unknown) — connected, but the whole transfer exceeded --max-time.Operation too slow. Less than N bytes/sec transferred the last M seconds — the low-speed guard (--speed-limit/--speed-time) fired.Recent curl versions also report a connect-phase timeout as Failed to connect to example.com ... after 10002 ms: Timeout was reached; the exit code is still 28. It is not exit 7 (CURLE_COULDNT_CONNECT: the host answered and refused), and not exit 6 (the name does not exist). A timeout means silence: nothing answered at all within the limit.
| Message | What stalled | Usual cause | Where to look |
|---|---|---|---|
| Resolving timed out | DNS lookup | Resolver in /etc/resolv.conf unreachable or dropping UDP/53 | dig example.com, resolver config |
| Connection timed out / Timeout was reached | TCP or TLS handshake | Firewall or cloud security group drops SYN, wrong IP in DNS, host down, outbound port blocked | nc -vz, tcpdump on the server |
| Operation timed out after N ms with X bytes | The response | Slow backend, long query, large file with a short --max-time | Server and application logs |
| Operation too slow | Throughput | Congested link, throttling, stalled upload | --speed-limit settings, the path |
The defaults matter. libcurl's connect timeout defaults to 300 seconds (CURLOPT_CONNECTTIMEOUT) and the overall timeout (CURLOPT_TIMEOUT) to 0, meaning never. So when you see error 28 after a few seconds, some code set a limit: your script, a wrapper library, a CI job or a .curlrc. A limit of 2 seconds on an endpoint that needs 3 is a configuration problem, not a network one.
A connect timeout where the TLS handshake is the slow part is still reported as a connection timeout: the curl manual says the connection phase is complete only «when the DNS lookup and requested TCP, TLS or QUIC handshakes are done».
Everything built on libcurl reports the same code. PHP returns 28 from curl_errno() with the same text from curl_error(); the limits are CURLOPT_CONNECTTIMEOUT and CURLOPT_TIMEOUT (or their _MS variants). Git prints it inside its own error, for example error: RPC failed; curl 28 Operation too slow.... Git's low-speed guard is configurable: http.lowSpeedLimit and http.lowSpeedTime, or the GIT_HTTP_LOW_SPEED_LIMIT and GIT_HTTP_LOW_SPEED_TIME environment variables (git-config).
Behind a proxy, the timeout may be on the way to the proxy rather than to the site. Run env | grep -i _proxy first: a stale https_proxy pointing at a host that no longer exists produces exactly this error for every URL.
-w variables show where the seconds go:curl -sS -o /dev/null --max-time 60 \
-w 'dns:%{time_namelookup} tcp:%{time_connect} tls:%{time_appconnect} ttfb:%{time_starttransfer} total:%{time_total}\n' \
https://example.com/A large dns value points at the resolver, a large gap between dns and tcp at the network path, and a large gap between tls and ttfb at the application.dig example.com and dig example.com @1.1.1.1. If only the first hangs, fix /etc/resolv.conf or the resolver it names.nc -vz -w 5 example.com 443. On the server, watch whether the SYN arrives at all:tcpdump -ni any 'tcp port 443 and tcp[tcpflags] & tcp-syn != 0'No packets means a firewall, security group or routing problem before the server. Packets but no reply means the host firewall drops them or nothing listens (ss -ltn 'sport = :443').curl --connect-timeout 10 --max-time 300 --retry 3 https://example.com/file.tar.gzThe curl manual counts a timeout as a transient error, so --retry covers it.curl -sS -o /dev/null -w '%{http_code} %{time_total}s\n' --connect-timeout 10 https://example.com/
# 200 0.412s
echo $?
# 0Run it from the machine that failed, not only from your laptop: a timeout is a property of the path. To see whether the host and port answer from a network outside yours, use the ping and port checker.
Ping sends ICMP packets to a host and measures response time. Port scanning checks which TCP ports are open and accepting connections — helping diagnose serviceavailability issues.
Choose packet count (3, 4, 6, 10). Stats: min/avg/max latency and packet loss.
Check 14 key ports: HTTP, HTTPS, SSH, FTP, SMTP, MySQL, PostgreSQL, and more.
Testing from our server — see site availability from outside, not just your local network.
Need constant monitoring? Create a monitor — checks every minute with notifications.
availability diagnosis
TCP port scanning
connection debugging
basic health check
Ping check history, host availability monitoring and downtime alerts.
Sign up freeError 7 means the connection attempt got an answer and failed, usually a refused port. Error 28 means nothing answered before the time limit ran out, which points at a firewall dropping packets, a wrong address or a stalled server.
libcurl waits up to 300 seconds to connect and has no overall limit by default. If you get error 28 after a few seconds, a timeout was set explicitly by your command, script, library or .curlrc.
The connection phase only: the DNS lookup and the TCP, TLS or QUIC handshake. The transfer after that is limited by --max-time.
Git uses libcurl, and its low-speed guard aborts transfers slower than http.lowSpeedLimit for http.lowSpeedTime seconds. Fix the slow link or proxy, or adjust those two settings for a very large repository.
Only after you know which phase is slow. A connect timeout is rarely fixed by waiting longer, because a dropped SYN never gets an answer; a slow download may legitimately need a larger --max-time.
Free plan — 10 monitors, checks every 5 min, no card required. Upgrade for 1-minute interval and multi-region monitoring.