Skip to content

cURL download file: save files, resume downloads and use a proxy

Download files with curl: -o, -O, -J, folders, -C - to resume, why --retry restarts in older curl, and proxies. Every command run on 10 October 2026.

HProxy TeamOctober 10, 2026Updated October 10, 202614 min read

cURL download file: save files, resume downloads and use a proxy

To download a file with curl, add -O to keep the file name from the URL, or -o and a name of your own. Add -L so curl follows redirects, and -f so it does not save an error page as your file. If the download breaks, run the same command with -C - added, and curl continues where it stopped.

curl -L -f -O https://example.com/file.zip

We ran every command below on October 10, 2026. Most ran with curl 8.5.0, the version Ubuntu 24.04 ships, and some with curl 8.21.0, the copy in Windows 11. Our test file was a 165,028-byte PNG on our own site. The two versions behave differently in three places, and this page shows where.

How do you download a file with curl?

You need curl, which Windows 10 and 11, macOS and most Linux systems include. What is cURL? shows how to check your version, and the version matters here more than usual.

Step 1: choose the name with -o

curl -o tracker.png https://hproxy.com/blog/_assets/img/amazon-price-tracker-check-output.png
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100  161k  100  161k    0     0   269k      0 --:--:-- --:--:-- --:--:--  269k

-o writes the body to the file you name. The meter shows 161k for 165,028 bytes, because curl counts 1k as 1,024 bytes.

Step 2: keep the name from the URL with -O

curl -O https://hproxy.com/blog/_assets/img/amazon-price-tracker-check-output.png

-O saved the file as amazon-price-tracker-check-output.png, the last part of the URL. Three details came out of our runs:

  • The query string is dropped. robots.txt?v=2 was saved as robots.txt.
  • A file of the same name is overwritten without a question.
  • A URL that ends in a slash has no name to take. curl 8.5.0 stopped with exit 23 and Failed writing received data to disk/application. curl 8.21.0 saved the same page as curl_response, the fallback the manual gives for 8.10.0 and newer.

Step 3: let the server choose the name with -J

curl -OJ 'https://httpbin.org/response-headers?Content-Disposition=attachment%3B%20filename%3Dreport.csv'

A server can suggest a name in its Content-Disposition header, which RFC 6266 defines. -J tells -O to use it, and our run saved report.csv. curl does not overwrite an existing file this way unless you add --clobber. The manual also warns that a hostile server could pick a dangerous name, such as a DLL on Windows.

Redirects change the name as well. After a redirect, -O still names the file after the first URL. Our download through httpbin's redirect-to address was saved as redirect-to on both builds. With -OJ, curl 8.21.0 named it after the target, llms.txt, while curl 8.5.0 still wrote redirect-to. The manual dates that fallback to curl 8.19.0.

Step 4: save into a folder

curl --create-dirs --output-dir downloads/2026-10 -O https://hproxy.com/robots.txt

--output-dir (curl 7.73.0 and newer) puts the file in that folder. It fails when the folder does not exist, so --create-dirs creates it. Our run made downloads/2026-10 and saved the 910-byte file inside.

Step 5: download several files

Give every URL its own -O, or put --remote-name-all in front to apply -O to all of them. -Z (--parallel, from curl 7.66.0) fetches them at the same time, 50 at most by default.

curl -# -O https://hproxy.com/robots.txt -O https://hproxy.com/llms.txt

-# swaps the meter for a simple bar. Our two files came without a stated size, so the bar showed only #=#=# for each.

Our own run on our server, October 10, 2026, 19:18 UTC: curl 8.5.0 on Ubuntu 24.04, captured off-screen. Each command is printed before its output, then its exit code.

How do you know the file is the one you wanted?

Exit code 0 means curl finished the transfer, not that you got the file. Two failures in our run exited 0 and still left a file behind.

Our own run on our server, October 10, 2026, 19:22 UTC: curl 8.5.0 on Ubuntu 24.04, captured off-screen. The test file is a 165,028-byte PNG on our own site.

A redirect page saved as your file

Our site sends http:// visitors to https:// with a 301. Without -L, curl saved that answer under the name robots.txt:

$ curl -sO http://hproxy.com/robots.txt; head -c 75 robots.txt
<html>
<head><title>301 Moved Permanently</title></head>
<body>
<center>

With -L, the same command saved the real 910-byte file. Following redirects with curl covers the limits and what happens to logins.

An error page saved as your file

A missing file gave a 404, and curl saved the error page as report-2026.zip with exit code 0. The file command found an HTML document inside. With -f, curl stopped with exit 22 and wrote no file:

$ curl -sSfO https://hproxy.com/report-2027.zip; ls -l report-2027.zip
curl: (22) The requested URL returned error: 404
ls: cannot access 'report-2027.zip': No such file or directory

If you want the error page and the exit code, use --fail-with-body, from curl 7.76.0.

Check the size, a hash or a signature

After the download, compare the file with what the publisher states. -w '%{http_code} %{size_download}' makes curl print the status and the byte count. sha256sum on Linux, or Get-FileHash in PowerShell, prints a SHA-256 hash to compare with a published one.

curl's own releases come with a signature instead. We checked curl 8.22.0 the way curl's verify page describes, with the release key from the link on that page:

curl -sSfLO https://curl.se/download/curl-8.22.0.tar.xz
curl -sSfLO https://curl.se/download/curl-8.22.0.tar.xz.asc
curl -sSf -o curl-key.asc 'https://keyserver.ubuntu.com/pks/lookup?op=get&search=0x27edeaf22f3abceb50db9a125cc908fdb71e12c2'
gpg --import curl-key.asc
gpg --verify curl-8.22.0.tar.xz.asc curl-8.22.0.tar.xz
gpg: Signature made Wed Sep  2 07:48:56 2026 CEST
gpg:                using RSA key 27EDEAF22F3ABCEB50DB9A125CC908FDB71E12C2
gpg: Good signature from "Daniel Stenberg <daniel@haxx.se>" [unknown]
gpg: WARNING: This key is not certified with a trusted signature!
gpg:          There is no indication that the signature belongs to the owner.
Primary key fingerprint: 27ED EAF2 2F3A BCEB 50DB  9A12 5CC9 08FD B71E 12C2

We gave each gpg command --homedir ./gpg, a throwaway keyring; your own gpg needs no extra option. The fingerprint is the one curl's verify page lists. The warning means gpg itself cannot vouch for the key. Comparing the fingerprint with the publisher's own page is the step that does.

Our own run on our server, October 10, 2026, 19:27 UTC: curl 8.5.0 and gpg 2.4.4 on Ubuntu 24.04, and a stub proxy we wrote, listening on 127.0.0.1 with the login USER:PASS.

How do you resume a broken download?

Add -C - to the same command. The dash tells curl to read the size of the partial file and ask the server for the rest.

curl -C - -o part.png https://hproxy.com/blog/_assets/img/amazon-price-tracker-check-output.png

In our run, a download cut after 3 seconds stopped at 89,337 of 165,028 bytes, with exit 28. The resume printed ** Resuming transfer from byte position 89337 and fetched the other 75,691 bytes. sha256sum gave the same hash for the resumed file and for a straight download.

Running -C - on a file that is already complete does no harm. curl reported byte position 165,028, transferred nothing and exited 0.

Resuming needs the server's help. RFC 9110 lets a server ignore a Range request, and curl's manual notes that many servers then send the whole file. Our server announces accept-ranges: bytes for the test file, so it resumed.

Does --retry resume a broken download?

That depends on your curl version. Several guides pair -C - with --retry as if it always resumes. We cut the same download every 3 seconds and let --retry 3 try again:

curl versionWhat we ranWhat happened
8.5.0, Ubuntu 24.04--retry 3Four attempts, each from byte 0; exit 28; 80,158 bytes kept
8.5.0, Ubuntu 24.04--retry 3 -C -Four attempts, each from byte 0; exit 28; 53,212 bytes kept
8.21.0, Windows 11--retry 3 -C -The second attempt asked for the last 95,050 bytes; exit 0; whole file, same hash

curl's changelog explains the difference. Version 8.17.0, released on November 5, 2025, made curl keep a failed partial download for retry auto-resume. Ubuntu 24.04 ships 8.5.0, so its retries start over.

On an older curl, a shell loop does the same job, because each new run of curl -C - continues from the partial file. We added --limit-rate 20k -m 3 to cut each run after 3 seconds:

until curl --no-progress-meter --limit-rate 20k -m 3 -C - -o loop.png https://hproxy.com/blog/_assets/img/amazon-price-tracker-check-output.png; do sleep 1; done

On curl 8.5.0, the loop resumed at byte 86,477, finished on its third run and produced the right hash.

Our own runs, October 10, 2026: above, curl 8.5.0 on our Ubuntu 24.04 server at 19:23 UTC; below, the curl.exe 8.21.0 that Windows 11 ships, on our workstation at 19:24 UTC. Same 165,028-byte file, each attempt cut after 3 seconds.

More retry rules from the manual: --retry is off by default. It covers timeouts and the HTTP codes 408, 429, 500, 502, 503 and 504, as the manual of curl 8.5.0 lists them; the current manual adds 522 and 524. curl waits 1 second, then doubles the wait up to 10 minutes, and --retry-delay sets a fixed wait instead. --retry-all-errors retries any error, and the manual calls it the sledgehammer of retrying.

How do you limit the download speed?

--limit-rate caps the speed in bytes per second, with k and M counted in steps of 1,024. The cap is an average over several seconds, so a short download can beat it. Our 20k cap allowed 26,847 and 29,429 bytes per second in two downloads cut at 3 seconds. --max-filesize refuses a file above a size you set, with exit 63.

How do you download a file through a proxy?

A download takes a proxy like any other curl request: -x for the proxy and -U for its login.

curl -x http://premium.hproxy.com:10000 -U USER:PASS -O https://example.com/file.zip

We tested this against a stub proxy on our server that asked for the login USER:PASS. The lower half of the capture above shows the run:

What we ranResultWhat the proxy saw
-x http://127.0.0.1:18081 -U USER:PASS -O on robots.txtStatus 200, 910 bytes savedCONNECT hproxy.com:443 with the login header
-x socks5h://USER:PASS@127.0.0.1:11081 on the PNGStatus 200, 165,028 bytes savedThe name hproxy.com, looked up by the proxy
-x http://127.0.0.1:18081 -O on llms.txt, no loginExit 56, CONNECT tunnel failed, response 407The request, refused; no file was created

A refused proxy leaves no file behind, unlike an error page from the site itself. How to use proxies with curl covers the proxy schemes and environment variables. The cURL proxy error guide decodes the exit codes. Some downloads must come from another country. For those, our residential proxies take the same -x and -U flags, with the host, port and login from your dashboard.

How do you download a file on Windows?

Windows 10 and 11 include curl.exe, and the options on this page work the same in it. In PowerShell, three details matter:

  • In Windows PowerShell 5.1, type curl.exe, because curl alone runs Invoke-WebRequest. What is cURL? shows the errors that follow.
  • Write -o nul where Linux uses -o /dev/null.
  • Save with -o, never with >.

We downloaded our PNG three ways on Windows 11, with the curl.exe it ships:

How we saved itBytesFirst bytesSame as the original?
curl.exe -o ok.png URL165,02889 50 4e 47Yes
curl.exe URL > ps51.png in Windows PowerShell 5.1313,602ff fe fd ffNo, the image is broken
curl.exe URL > ps7.png in PowerShell 7.6.6165,02889 50 4e 47Yes
One 165,028-byte image, saved three ways on Windows
curl.exe URL > file, in Windows PowerShell 5.1broken: Out-File wrote UTF-16 text
313,602 bytes
curl.exe -⁠o file URLthe same as the original
165,028 bytes
curl.exe URL > file, in PowerShell 7.6.6the same as the original
165,028 bytes
Source: HProxy, curl.exe 8.21.0 on Windows 11 · hproxy.comProxy.

Windows PowerShell 5.1 sends > through Out-File, which writes UTF-16 text by default, so a binary file comes out broken. PowerShell 7.4 changed redirection to keep the bytes of programs like curl. -o works the same in every shell.

What goes wrong most often?

What you seeWhyWhat to do
The file holds 301 Moved Permanentlycurl saved the redirect pageAdd -L
The file is an HTML error page, and the exit code is 0curl saved the error pageAdd -f
curl: (23) Failed writing received data to disk/application with -OThe URL ends in a slash, on curl older than 8.10.0Name the file with -o
The file is called redirect-to-O took the name of the first URLUse -o, or -OJ on curl 8.19.0 or newer
--retry starts again from zerocurl older than 8.17.0Loop curl -C - until it exits 0
A broken image or archive after > in PowerShell 5.1Out-File wrote UTF-16 textSave with -o
curl: (56) CONNECT tunnel failed, response 407The proxy wants a loginAdd -U
curl: (28) Operation timed out-m ran out, or the network is slowRaise -m, then resume with -C -

What this page could not check

We ran two curl builds: 8.5.0 on Ubuntu 24.04 and 8.21.0 on Windows 11. macOS and other Linux distributions were not run. We cut downloads with --max-time instead of a real network drop. Resuming was tested on our own server, which honors ranges, and a server that ignores Range was not tested. The signature check rests on the key that curl's site links, and gpg cannot make that call for you. The proxy runs used a stub on our server, not a commercial network. Microsoft's redirection page for PowerShell 5.1 says it writes UTF-8, but its Out-File page and our test both point to UTF-16. curl releases about every eight weeks, so we will check the version notes on this page again by January 10, 2027.

Sources

  • curl manual for download options (the man page of version 8.23.0), read October 10, 2026: curl.se/docs/manpage.html.
  • curl project, changelog, with 8.17.0 of November 5, 2025, read October 10, 2026: curl.se/changes.html.
  • curl project, download page and verify page, read October 10, 2026: curl.se/docs/verify.html.
  • RFC 9110, HTTP Semantics, June 2022, for range requests, 301 and 416: rfc-editor.org/rfc/rfc9110.
  • RFC 6266, Content-Disposition in HTTP, June 2011: rfc-editor.org/rfc/rfc6266.
  • GnuPG manual, Operational GPG Commands, read October 10, 2026: gnupg.org.
  • Microsoft Learn, Out-File and about_Redirection (PowerShell 5.1), updated in July and September 2023: learn.microsoft.com.
  • Microsoft Learn, What's New in PowerShell 7.4, updated September 8, 2026: learn.microsoft.com.
  • Microsoft Learn, Get-FileHash, updated December 12, 2022: learn.microsoft.com.
  • Our own downloads of October 10, 2026, with curl 8.5.0 on Ubuntu 24.04 and curl.exe 8.21.0 on Windows 11. They fetched from our own site, httpbin.org and curl.se, partly through a stub proxy we wrote. Every transcript, capture and script sits in this page's research folder.

Frequently asked questions

How do I download a file with curl?

Use -O to keep the file name from the URL, or -o and a name of your own, for example curl -L -f -O https://example.com/file.zip. -L follows redirects, and -f stops curl from saving an error page as your file. In Windows PowerShell 5.1, type curl.exe.

What is the difference between curl -o and -O?

-o (lower case) saves the download under the name you write after it. -O (upper case) takes the name from the last part of the URL, without the query string, and overwrites a file of that name. Use one -o or -O per URL.

How do I resume a download with curl?

Run the same command again with -C - added, for example curl -C - -o file.zip URL. curl reads the size of the partial file and asks the server for the rest. In our test it resumed at byte 89,337, and the result matched a full download. The server has to support ranges.

Does curl --retry resume a broken download?

Only in curl 8.17.0 and newer, and only with -C - added. In curl 8.5.0, the version Ubuntu 24.04 ships, every retry started from zero in our test. On an older curl, run curl -C - in a loop until it exits 0.

How do I keep the file name the server sends?

Add -J to -O: curl -OJ URL. curl then uses the filename from the Content-Disposition header. It does not overwrite an existing file of that name. Since curl 8.19.0, -OJ also falls back to the name of the file a redirect points to.

Why is the file I downloaded with curl an HTML page?

Either the server redirected you and curl saved the redirect page, so add -L, or the server sent an error page, which curl saves with exit code 0, so add -f. With -f, curl exits with code 22 and writes no file.

How do I download a file through a proxy with curl?

Add -x with the proxy address and -U with its login, for example curl -x http://premium.hproxy.com:10000 -U USER:PASS -O URL. For a SOCKS5 proxy, write socks5h:// so the proxy looks up the name. A refused login ends with exit 56 and no file.

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