Skip to content

--retry doesn't retry on connection timeout, if you don't pass --connect-timeout #4461

@njsmith

Description

@njsmith

I did this

240.0.0.1 is a reserved IP address, so connections to it should just time out. When using --retry, I expected curl would report a timeout, and then retry the connection as requested. Instead, it reports a timeout, and doesn't retry the connection:

~$ curl --retry 5 -v http://240.0.0.1                 
* Expire in 0 ms for 6 (transfer 0x557c953145c0)
*   Trying 240.0.0.1...
* TCP_NODELAY set
* Expire in 200 ms for 4 (transfer 0x557c953145c0)
* connect to 240.0.0.1 port 80 failed: Connection timed out
* Failed to connect to 240.0.0.1 port 80: Connection timed out
* Closing connection 0
curl: (7) Failed to connect to 240.0.0.1 port 80: Connection timed out

If I add an explicit --connect-timeout 10, then it works as expected:

~$ curl --connect-timeout 10 --retry 5 -v http://240.0.0.1                 
* Expire in 0 ms for 6 (transfer 0x5577b299d5c0)
* Expire in 10000 ms for 2 (transfer 0x5577b299d5c0)
*   Trying 240.0.0.1...
* TCP_NODELAY set
* Expire in 200 ms for 4 (transfer 0x5577b299d5c0)
* Connection timed out after 10001 milliseconds
* Closing connection 0
Warning: Transient problem: timeout Will retry in 1 seconds. 5 retries left.
* Expire in 0 ms for 6 (transfer 0x5577b299d5c0)
* Expire in 10000 ms for 2 (transfer 0x5577b299d5c0)
* Hostname 240.0.0.1 was found in DNS cache
*   Trying 240.0.0.1...
* TCP_NODELAY set
* Expire in 200 ms for 4 (transfer 0x5577b299d5c0)
^C

I suspect the problem is that curl's retry logic doesn't know that connect resolving with ETIMEDOUT should be treated as a connect that timed out.

I can sort of see the justification for this, even, if I squint. But this really confused me. In the real situation where I ran into this, I was getting transient errors in CI runs, and curl was reporting them as "connection timed out". So I checked the man page, it says --retry can be used to retry when connect times out, I added --retry, and then ... a few days later I got the error again. So then I thought there must be some kind of weird failure mode where the host was timing out all 6 connection attempts... I think ideally --retry should just work in this case, but if not then at least the man page should be updated to warn about this.

curl/libcurl version

curl 7.64.0 (x86_64-pc-linux-gnu) libcurl/7.64.0 OpenSSL/1.1.1b zlib/1.2.11 libidn2/2.0.5 libpsl/0.20.2 (+libidn2/2.0.5) libssh/0.8.6/openssl/zlib nghttp2/1.36.0 librtmp/2.3
Release-Date: 2019-02-06
Protocols: dict file ftp ftps gopher http https imap imaps ldap ldaps pop3 pop3s rtmp rtsp scp sftp smb smbs smtp smtps telnet tftp 
Features: AsynchDNS IDN IPv6 Largefile GSS-API Kerberos SPNEGO NTLM NTLM_WB SSL libz TLS-SRP HTTP2 UnixSockets HTTPS-proxy PSL 

operating system

Ubuntu 19.04

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions