Skip to content

SFTP: downloading an empty file on a reused connection results in CURLE_TOO_MANY_REDIRECTS #19165

Description

@blach

I did this

In my app, I'm using libcurl for getting directory listings and downloading files using SFTP.

When attempting to download an empty file after listing a directory (so the connection is reused), I get the error code CURLE_TOO_MANY_REDIRECTS.

I can reproduce the issue with command line curl using the "--next" parameter to issue two commands to the same server:

In the home directory on my server, I have created the folder "empty_file_test". This contains the 0 byte file "empty.txt".

mkdir empty_file_test
cd empty_file_test
touch empty.txt

On the client, I then issue this curl command (redacted):

curl -vvv sftp://server/~/empty_file_test/ --next sftp://server/~/empty_file_test/empty.txt --output empty.txt

Here's the redacted log file:

== Info: [READ] client_reset, clear readers
== Info: Host [redacted] was resolved.
== Info: IPv6: (none)
== Info: IPv4: [redacted]
== Info: [SETUP] added
== Info:   Trying [redacted]...
== Info: [SETUP] Curl_conn_connect(block=0) -> 0, done=0
== Info: [SETUP] Curl_conn_connect(block=0) -> 0, done=0
== Info: [SETUP] Curl_conn_connect(block=0) -> 0, done=0
== Info: [SETUP] Curl_conn_connect(block=0) -> 0, done=0
== Info: [SETUP] Curl_conn_connect(block=0) -> 0, done=0
== Info: [SETUP] Curl_conn_connect(block=0) -> 0, done=0
== Info: [SETUP] Curl_conn_connect(block=0) -> 0, done=0
== Info: [SETUP] Curl_conn_connect(block=0) -> 0, done=1
== Info: Established connection to [redacted] ([redacted] port 22) from [redacted] port 55451 
== Info: libssh2 cryptography backend: openssl compatible
== Info: User: '[redacted]'
== Info: Initialized password authentication
== Info: Authentication complete
<= Recv data, 66 bytes (0x42)
0000: -rw-r--r--    1 [redacted]   [redacted]          0 Oct 20 17:33 empty.tx
0040: t.
-rw-r--r--    1 [redacted]   [redacted]          0 Oct 20 17:33 empty.txt
== Info: [WRITE] [OUT] wrote 66 body bytes -> 66
== Info: [WRITE] [PAUSE] writing 66/66 bytes of type 1 -> 0
== Info: [WRITE] download_write body(type=1, blen=66) -> 0
== Info: [WRITE] client_write(type=1, len=66) -> 0
<= Recv data, 59 bytes (0x3b)
0000: drwx------   11 [redacted]   [redacted]       4096 Oct 20 16:59 ...
drwx------   11 [redacted]   [redacted]       4096 Oct 20 16:59 ..
== Info: [WRITE] [OUT] wrote 59 body bytes -> 59
== Info: [WRITE] [PAUSE] writing 59/59 bytes of type 1 -> 0
== Info: [WRITE] download_write body(type=1, blen=59) -> 0
== Info: [WRITE] client_write(type=1, len=59) -> 0
<= Recv data, 58 bytes (0x3a)
0000: drwxr-xr-x    2 [redacted]   [redacted]       4096 Oct 20 17:33 ..
drwxr-xr-x    2 [redacted]   [redacted]       4096 Oct 20 17:33 .
Info: [WRITE] [OUT] wrote 58 body bytes -> 58
Info: [WRITE] [PAUSE] writing 58/58 bytes of type 1 -> 0
Info: [WRITE] download_write body(type=1, blen=58) -> 0
Info: [WRITE] client_write(type=1, len=58) -> 0
Info: [WRITE] [OUT] done
Info: [READ] client_reset, clear readers
Info: Connection #0 to host [redacted]:22 left intact
Info: [READ] client_reset, clear readers
Info: Reusing existing SFTP: connection with host [redacted]
Info: abort upload
Recv data, 0 bytes (0x0)
Info: [WRITE] [PAUSE] writing 0/0 bytes of type 81 -> 0
Info: [WRITE] download_write body(type=81, blen=0) -> 0
Info: [WRITE] client_write(type=81, len=0) -> 0
Info: [WRITE] xfer_write_resp(len=0, eos=1) -> 0
Info: Connection died, retrying a fresh connect (retry count: 1)
Info: [WRITE] [OUT] done
Info: [READ] client_reset, will rewind reader
Info: shutting down connection #0
curl: (47) Number of redirects hit maximum amount

As you can see, this ends with "curl: (47) Number of redirects hit maximum amount".

This does not happen when just downloading an empty file without listing the directory first. I guess it only happens when a connection is reused.

I expected the following

There should be no error.

curl/libcurl version

curl 8.16.0 (aarch64-apple-darwin24.4.0) libcurl/8.16.0 OpenSSL/3.6.0 zlib/1.2.12 brotli/1.1.0 zstd/1.5.7 AppleIDN libssh2/1.11.1 nghttp2/1.67.1 ngtcp2/1.17.0 nghttp3/1.12.0 librtmp/2.3
Release-Date: 2025-09-10
Protocols: dict file ftp ftps gopher gophers http https imap imaps ipfs ipns ldap ldaps mqtt pop3 pop3s rtmp rtsp scp sftp smb smbs smtp smtps telnet tftp ws wss
Features: alt-svc AsynchDNS brotli GSS-API HSTS HTTP2 HTTP3 HTTPS-proxy IDN IPv6 Kerberos Largefile libz NTLM SPNEGO SSL threadsafe TLS-SRP UnixSockets zstd

operating system

Darwin Mac-Studio-von-Alexander.local 24.6.0 Darwin Kernel Version 24.6.0: Mon Aug 11 21:16:34 PDT 2025; root:xnu-11417.140.69.701.11~1/RELEASE_ARM64_T6020 arm64

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions