Skip to content

cURL timeout: connect-timeout, max-time and proxy timeouts

Set curl timeouts with --connect-timeout and --max-time. Seven cases measured: no timeout waited 133 s, each option stopped on time, a dead proxy named itself.

HProxy TeamOctober 11, 2026Updated October 11, 20266 min read

cURL timeout: connect-timeout, max-time and proxy timeouts

curl has three ways to stop waiting. --connect-timeout limits the connection, --max-time limits the whole transfer, and --speed-limit with --speed-time stops a transfer that crawls. Without them, curl can wait for a very long time.

We measured seven cases with curl 8.5.0 on Ubuntu 24.04 on 11 October 2026. With no option at all, curl spent 133 seconds on an address that never answered. Each option then stopped curl within a tenth of a second of its limit.

How do you set a timeout in curl?

Set both limits. A short one for connecting, a longer one for the whole request:

# give up if connecting takes over 10 s, or the whole transfer over 30 s
curl --connect-timeout 10 --max-time 30 https://example.com/

The curl manual describes --connect-timeout in one line: "Maximum time in seconds that you allow curl's connection to take." Once connected, curl carries on. --max-time sets "the maximum time in seconds that you allow each transfer to take", from start to finish. The manual says what that is for: "Prevents your batch jobs from hanging for hours due to slow networks or links going down." Both accept decimals, such as --max-time 2.5.

What happens without a timeout?

Less than you might think, and still too long. libcurl's documentation names a "default built-in connection timeout - 300 seconds". In our test that limit never came into play. curl tried to reach 192.0.2.1, an address reserved for documentation by RFC 5737, where nothing ever answers. It gave up after 133 seconds:

$ curl http://192.0.2.1/
curl: (28) Failed to connect to 192.0.2.1 port 80 after 133218 ms: Couldn't connect to server

The operating system stopped it first. On Linux, the kernel resends a connection attempt a limited number of times. Its manual says the default "corresponds to retrying for up to approximately 127 seconds". Our two runs took 133 and 135 seconds.

After the connection, there is no limit at all. For the transfer, libcurl's default is "0 (zero) which means it never times out". A server that accepts the request and then stays silent will hold curl for as long as it likes. We had to cap our own test at 20 seconds.

What did each option do in our test?

We ran each case against 192.0.2.1 or against a slow server of our own on the same machine. One page of that server never answers. The other sends one byte per second.

Terminal output: seven curl runs. No timeout ended after 133.2 s; --connect-timeout 5 after 5.1 s; --max-time 20 on a silent server after 20.0 s; --max-time 5 on a slow body after 5.0 s with 5 of 30 bytes; --speed-limit after 5.0 s; a dead proxy after 5.0 s naming port 8080; three retries after 8.1 s
Our own capture, 11 October 2026: timeouts.sh with curl 8.5.0 on our server

Every limit held to within a tenth of a second. Every timeout ended with the same exit code, 28, whichever limit was hit.

Which option stops which wait?

A request has three phases, and each option covers a different part of it:

Diagram: a request in three phases, connect, wait for an answer and receive the body. --connect-timeout covers the connect phase, --max-time all three, --speed-limit with --speed-time the wait and the body. With nothing set, the connect ended after 133 s and the rest had no limit
Diagram: HProxy, from our test of 11 October 2026
  • --connect-timeout covers the connection only. libcurl spells out what that includes: "the name resolve (DNS) and all protocol handshakes and negotiations until there is an established connection".
  • --max-time covers everything. It stopped our slow download at 5.0 seconds, with 5 of 30 bytes received.
  • --speed-limit with --speed-time watches the speed after the connection. The manual: "If a transfer is slower than this set speed (in bytes per second) for a given number of seconds, it gets aborted." It stopped the slow download at 5.0 seconds, and a silent server too.

A server that answers slowly but steadily never trips the speed limit. Only --max-time stops that one.

What does curl error 28 mean?

The manual's list of exit codes is short on this one: "28 Operation timeout. The specified time-out period was reached according to the conditions." The message after it tells you which limit was hit:

MessageLimit that was reached
Failed to connect ... after 5005 ms: Timeout was reached--connect-timeout
Failed to connect ... Couldn't connect to servernone set: the system gave up
Operation timed out after 5006 milliseconds with 5 out of 30 bytes received--max-time
Operation too slow. Less than 100 bytes/sec transferred the last 5 seconds--speed-limit with --speed-time

The bytes in the --max-time message are useful. 0 bytes means the server never answered. Part of the body means it was too slow.

How do timeouts work through a proxy?

The options work the same, and the proxy becomes part of the connection. We pointed curl at a proxy that never answers:

$ curl --connect-timeout 5 -x http://192.0.2.1:8080 http://example.com/
curl: (28) Failed to connect to 192.0.2.1 port 8080 after 5012 ms: Timeout was reached

The error names the proxy, 192.0.2.1 on port 8080, not example.com. That is the quickest way to tell a dead proxy from a dead site. If the address in the error is your proxy's, change the proxy. Our proxy checker shows which proxies answer before a script waits on them, and our residential proxies are the paid option.

How do retries and timeouts work together?

--retry repeats a transfer after a "transient error", which the manual defines as "a timeout, an FTP 4xx response code or an HTTP 408, 429, 500, 502, 503, 504, 522 or 524 response". We combined it with a 2-second connect limit:

curl --connect-timeout 2 --retry 2 --retry-delay 1 --retry-connrefused http://192.0.2.1/

curl tried three times and stopped after 8.1 seconds: three attempts of 2 seconds, plus the waits. Note one trap. The manual says "the maximum time counter is reset each time the transfer is retried", so --max-time limits each attempt, not the whole run. To cap the whole run, add --retry-max-time.

What this page could not check

  • One machine: curl 8.5.0 on Ubuntu 24.04 with the kernel's default settings. Other systems and versions can give other times and messages.
  • The slow server was our own program on the same machine. Real servers stall in other ways.
  • We did not test slow name lookups or TLS handshakes that stall.
  • The run without a timeout took 133 and 135 seconds, a little more than the 127 seconds the Linux manual gives.
  • We will run the test again with the current curl by 11 January 2027.

Sources

  • curl, man page, --connect-timeout, --max-time, --speed-limit, --speed-time, --retry and exit codes, read 11 October 2026: curl.se.
  • libcurl, CURLOPT_CONNECTTIMEOUT, read 11 October 2026: curl.se.
  • libcurl, CURLOPT_TIMEOUT, read 11 October 2026: curl.se.
  • Linux man-pages, tcp(7), tcp_syn_retries, the version installed on our server, read 11 October 2026: man7.org.
  • RFC 5737, IPv4 Address Blocks Reserved for Documentation, IETF, January 2010: rfc-editor.org.
  • Our own test: timeouts.sh with curl 8.5.0 on our server, 11 October 2026, 08:46 UTC, and a first run at 08:43 UTC.

Frequently asked questions

Does curl have a default timeout?

Not for the whole transfer: libcurl's default is 0, which never times out. For the connection, libcurl documents 300 seconds, but on Linux an address that never answered ended after 133 seconds in our test, because the kernel stopped retrying first.

What is the difference between --connect-timeout and --max-time?

--connect-timeout limits only the connection phase, from the name lookup to the finished handshakes. --max-time limits the whole transfer. Use both: a short limit for connecting and a longer one for everything.

What does curl error 28 mean?

Operation timeout: one of the time limits was reached. The message tells you which one. 'Timeout was reached' after 'Failed to connect' is the connection, 'Operation timed out after' is --max-time, and 'Operation too slow' is the speed limit.

How do I set a curl timeout through a proxy?

With the same options. --connect-timeout also limits the connection to the proxy. When the proxy does not answer, the error names the proxy's address and port, not the site's.

Does --max-time count all retries together?

No. curl resets the --max-time counter on every retry. Use --retry-max-time to cap the whole run.

How do I stop a download that stalls?

Use --speed-limit with --speed-time. With 100 bytes per second for 5 seconds, curl stopped a transfer that sent 1 byte per second after 5.0 seconds, and a server that sent nothing at all after 5.0 seconds too.

Get proxies that are alive right now

Our free proxy list re-checks every exit every few minutes across 100+ countries, with a live last-checked time, so you copy IPs that worked moments ago, not a stale text dump. When the location has to survive a real check, the paid network holds up.

129M+ proxy checks run · 100+ countries · HTTP / HTTPS / SOCKS · re-checked every few minutes · no signup

HProxy.

Honest guides and comparisons on proxies, scraping and staying unblocked, from the team that runs the network.

RSS feed