How to download and resume files with cURL
To download a file with cURL, give it a URL and an output filename with -o. The walkthrough below
saves a source archive from the curl project, follows redirects, and shows how to continue the
download if it stops partway through.
Check cURL in your terminal
Open a terminal in a directory where you can save files. These examples use Bash-style commands and were tested on macOS with cURL 8.7.1 and 8.22.0. Check your installed version first:
curl --version
The first line should start with curl and a version number. If the command is missing, use the
curl download page to find an installation for your platform.
Download to a local file
This downloads the curl 8.22.0 source archive as an example file. You do not need to build or install it. The command overwrites an existing file with the same name, so choose a different output name if you need to keep that file.
curl -fsSLo curl-8.22.0.tar.xz 'https://curl.se/download/curl-8.22.0.tar.xz'
The short options are combined into -fsSLo:
| Option | What it does |
|---|---|
-f (--fail) | Reports HTTP errors such as 404 as a failed transfer. |
-s (--silent) | Hides the progress meter. |
-S (--show-error) | Keeps error messages visible when using -s. |
-L (--location) | Follows HTTP redirects. |
-o (--output) | Saves the response to the filename that follows it. |
These options are documented in the curl manual.
Without an output option, cURL writes to standard output, which is usually your terminal.
With -o, it writes to a file
in the current directory unless you supply another path.
The -L matters when a download link redirects to another location: cURL requests the destination
and saves its response to your chosen filename. Keep it in both the initial download and the resume
command below.
On success, this command is quiet and returns you to the prompt. Check the saved size:
wc -c < curl-8.22.0.tar.xz
For this archive, the count is 2953092 bytes. That checks the size, not the contents; use the
publisher’s checksum when you need to verify the downloaded bytes. To download your own file,
replace both the URL and the output filename. Keep the URL quoted so shell characters such as &
do not split the command.
Recognize a failed download
With -f, a response such as HTTP 404 or 500 makes cURL exit with code 22 and an error message,
without saving the server’s error page as your download. Without -f, an HTTP error response can
look like a successful transfer. See the manual’s --fail behavior.
A network failure can still leave a partial file on disk. The presence of a file alone does not
prove that the transfer finished. If the URL returns a login page with HTTP 200, -f will not catch
that either: cURL cannot tell whether those bytes are the file you intended to download.
Resume an interrupted download
If a download stops, keep its partial file. To try this yourself, start a fresh download with a speed
limit, then press Ctrl+C after a few seconds. This deliberately overwrites the archive you just
downloaded. The progress meter is visible here because the command omits -s.
curl -fSL --limit-rate 50K -o curl-8.22.0.tar.xz 'https://curl.se/download/curl-8.22.0.tar.xz'
Continue from the same directory, using the same output filename and URL:
curl -fsSL -C - -o curl-8.22.0.tar.xz 'https://curl.se/download/curl-8.22.0.tar.xz'
The - after -C tells cURL to use the local file’s size as the starting byte offset. For HTTP,
the server must honor the range request so cURL can append the remaining bytes. The
curl guide to resuming downloads
explains how the offset is chosen. After the command succeeds, repeat the size check above.
If the server ignores the range request, cURL reports error 33 instead of resuming. Restart with
the original download command, without -C -, to replace the partial file with a complete download.
Only resume a file whose remote contents have not changed. cURL uses the length of your partial file; it does not compare the bytes already saved with the server’s copy. A changed remote file can therefore produce a mixture of old and new content even when the transfer succeeds. A versioned download URL, like the archive used here, avoids relying on a moving “latest” URL. If you are unsure whether the file changed, start over.
For uploading files to run a Transloadit Template, see the API guide to creating an Assembly.
