FTP Resume: How to Recover Interrupted Transfers
Internet connections drop. FTP clients crash. Laptops sleep mid- transfer. The FTP and SFTP protocols both support resuming interrupted transfers from where they left off — but the mechanics, the commands, and the gotchas differ. Here's the guide to resume support: how the protocol-level commands work, how to enable it in your client, and what to watch out for.
When an FTP or SFTP transfer drops halfway through a multi-gigabyte file, restarting from byte zero is the wrong answer — and both protocols know it. FTP supports resume via the REST command (specified in RFC 3659, 2007), letting the client tell the server "resume this transfer at byte offset N." SFTP supports resume natively via the reget and reput commands, which read or write into an existing file from the offset the client computes itself. Most modern clients handle resume automatically when configured to; the rest of this post covers the protocol-level mechanics, the client configuration, and the failure modes that look like resume problems but aren't.
How resume works in FTP
FTP's resume support is built on four protocol-level commands, all standardized in RFC 3659:
| Command | What it does |
|---|---|
REST <offset> | Sets the restart marker — next transfer resumes at this byte offset |
SIZE <file> | Returns the current size of a file on the server |
MLST <file> | Returns metadata about a single file |
MLSD <dir> | Lists directory contents in a machine-readable format |
The actual resume exchange:
- Client checks how much of the file is already on the server. For an upload, the client sends
SIZE filename.datto find out how many bytes are already there. For a download, the client checks its local file's size instead. - Client tells the server where to resume from.
REST 1048576says "start at byte 1,048,576." The server accepts the marker but doesn't transfer anything yet. - Client triggers the actual transfer.
STOR filename.dat(upload) orRETR filename.dat(download). The server starts writing or reading from the offset the client set.
In practice, the FTP client handles all this transparently — you don't type REST directly. The user-facing experience is "the transfer failed at 47%; reconnecting and clicking resume picks up at 47%."
How resume works in SFTP
SFTP's resume model is simpler because the protocol is built on SSH and supports random-access reads and writes natively. Two CLI commands:
sftp> reget bigfile.iso # resume an interrupted download
sftp> reput bigfile.iso # resume an interrupted upload
reget opens the local file, checks its size, and asks the server for the rest of the bytes starting at that offset. reput does the same in reverse — checks the server's current file size, opens the local file at that offset, and resumes the upload from there.
The underlying SFTP protocol carries explicit SSH_FXP_READ and SSH_FXP_WRITE operations with byte-offset parameters, so the resume is at the protocol level rather than a special-case command. Every SFTP client and library implements this; the user-facing experience is the same as FTP — "reconnect, resume from where it stopped."
Resuming vs overwriting: which one do you want?
Resume restarts the transfer from where it left off, without re-verifying the bytes already transferred. If the source file changed between the original transfer and the resume, the resulting file on the destination is a mix of old bytes (from the interrupted transfer) and new bytes (from the resume) — corrupt and silently so.
Use resume when:
- You're confident the source file hasn't changed since the original transfer.
- The original transfer was interrupted by network or client failure, not by intentional cancellation.
- The cost of re-transferring from byte zero is significant (large files, slow connections).
Use overwrite (transfer the file from byte zero) when:
- The source file might have changed.
- You're not confident about the integrity of the partial bytes on the destination.
- The file is small enough that the resume savings don't matter.
When in doubt, overwrite — corrupted-and-undetected is a worse outcome than re-transferring 47% of a file.
How to enable resume in common clients
FileZilla (FTP/SFTP, graphical):
- Resume is on by default. When a transfer fails, the partial file remains; reconnect and re-queue the same file. FileZilla detects the partial and prompts: "Resume from X bytes?" Accept to resume.
- The behavior is configurable in Edit → Settings → File Transfer → Existing files action.
WinSCP (FTP/SFTP, graphical):
- Resume is on by default for SFTP. For FTP, depends on whether the server supports
REST(most do). - Configurable per-session in Advanced → File transfer → Resume / transfer to temporary filename.
Command-line sftp (OpenSSH):
- Use
regetandreputexplicitly:sftp> reget bigfile.iso sftp> reput bigfile.iso - The standard
getandputdon't auto-resume; they overwrite from byte zero.
Command-line ftp (legacy):
- The OS-bundled
ftpcommand rarely supports resume in a useful way. For scripted FTP, uselftporcurlinstead.
lftp (CLI, scriptable):
- Auto-resume with the
-cflag:lftp -e "get -c bigfile.iso" sftp://user@host lftp -e "put -c bigfile.iso" sftp://user@host -cmeans "continue" — exactly the resume behavior.
curl (one-off transfers):
- The
--continue-at -flag tells curl to figure out the resume offset automatically:curl --continue-at - -O sftp://user@host/bigfile.iso - Works for both upload (
-T) and download (-O).
Python paramiko (SFTP automation):
- Manually compute the offset and use
SFTPClient.putorgetwith theconfirm=Trueoption:import os remote_size = sftp.stat(remote_path).st_size local_size = os.path.getsize(local_path) if local_size < remote_size: with sftp.open(remote_path, "rb") as remote, \ open(local_path, "ab") as local: remote.seek(local_size) local.write(remote.read()) paramikodoesn't have a built-in resume helper; you build it from primitives.
Common failure modes that look like resume problems
"The transfer says 100% but the file is half the size."
The transfer reported success but the byte count is wrong. Almost always means the client thought it was uploading a new file but the server already had a partial copy with that name from a previous session, and the resume logic (or the client's "skip existing files" setting) made it think the upload completed without sending any bytes. Check the file size at both ends; if they don't match, force-overwrite from byte zero.
"The resumed file is corrupted."
The source file changed between the original transfer and the resume. Or the source was an in-progress write that wasn't yet flushed when the resume started. Either way, the bytes don't match. Force-overwrite and avoid resume for files written by other processes mid-transfer.
"The resume keeps starting over from byte zero."
Two possibilities. The server doesn't support REST (unusual but possible on very old FTP servers — check with the FEAT command). Or the client's resume-detection logic isn't triggering — check that the partial file on the destination has the exact same filename, and that "overwrite" isn't the default action in the client's UI.
"-resumesupport=off errors in FTP scripting."
Some FTP servers explicitly disable resume support, and clients querying for REST capability get a refusal. The -resumesupport=off flag in lftp and other tools forces the client to skip resume detection entirely. If you see this error or flag, the server is the culprit; either ask the server admin to enable REST support or accept overwriting from byte zero.
"SFTP stalled — how do I resume?"
If the SFTP session itself is stalled (connection idle, no data flowing), the fix is to kill the client, reconnect, and use reget or reput (depending on direction). Most SFTP clients won't auto-resume a stalled session; they'll prompt or wait for the user to retry.
Resume isn't a substitute for chunked transfer
For very large files where partial transfers are routine, modern alternatives to "FTP with resume" are usually better:
- Multipart upload to object storage (S3, GCS, Azure Blob) — splits the file into discrete chunks each uploaded independently, with automatic retry on chunk failure. Much more resilient than FTP resume.
- rsync over SSH — block-level differential, only transfers the parts of the file that changed. Resume is implicit.
- A platform with built-in retry — managed-file-transfer platforms typically retry failed transfers automatically without exposing the resume primitives to the user.
For occasional resumes (you transferred a 5 GB file, the WiFi dropped, you want to finish), FTP resume is fine. For routine large-file workflows, the protocol you're starting with is probably the wrong tool.
The modern way
Files.com is the File Orchestration Platform we'd recommend for any team running large-file or recurring-transfer workflows in 2026. The platform handles resume natively across SFTP, FTPS, FTP, and HTTPS — your clients see resume behavior consistently regardless of which protocol they use, and the platform layer adds:
- Automatic retry with exponential backoff for the platform's own automation.
- Multipart upload support for very large files via the REST API.
- Audit logging on every transfer including partial transfers — easier to diagnose "the file didn't fully upload" tickets.
- Webhook notifications on transfer completion so downstream automation only fires after the full file arrives.
Start a free Files.com trial — no credit card, provisioned in about 10 minutes.
For the narrow set of teams that must run file-transfer infrastructure inside their own datacenter, the free ExaVault on-premise appliance ships the same protocols with resume support from a self-hosted VM image.
FAQ
Does FTP support resuming transfers?
Yes — via the REST command, standardized in RFC 3659 (2007). Most FTP servers and clients support it; the user-facing experience is "transfer fails, reconnect, click resume."
Does SFTP support resuming transfers?
Yes — natively, with the reget (download) and reput (upload) commands in the CLI, or with seek-based reads and writes in the SFTP protocol. Most graphical SFTP clients (FileZilla, WinSCP, Cyberduck) auto-resume on reconnect.
Will FileZilla automatically resume an interrupted transfer?
Yes, when configured to. Re-queue the same file after the transfer fails; FileZilla detects the partial and prompts to resume. If you don't see the prompt, check Edit → Settings → File Transfer → Existing files action — make sure "Resume" is one of the options.
What's the FTP command to resume a transfer?
REST <offset> sets the restart marker, followed by STOR <file> (upload) or RETR <file> (download). Most clients do this automatically; you'd only type these manually if you were driving the FTP protocol with telnet or a raw shell.
What's -resumesupport=off?
A flag in lftp (and similar in some other tools) that disables resume-detection logic. Used when the server doesn't support REST or returns garbage when asked. Forces overwrite-from-zero behavior instead.
Why does my resumed file end up corrupted?
Almost always because the source file changed between the original transfer and the resume. Resume restarts from a byte offset without verifying that the bytes before that offset match between source and destination — if the source changed, the result is a mix of old and new bytes. Force-overwrite from byte zero when the source might have changed.
How do I resume an interrupted upload over SFTP?
In the CLI: reput filename. In FileZilla / WinSCP / Cyberduck: re-queue the same file and accept the resume prompt. In Paramiko: read the remote file size, open the local file at that offset, and write the remaining bytes.
Is there a maximum file size for FTP resume?
No protocol-level limit. The REST command accepts byte offsets up to 2^64 - 1, which is more than 18 exabytes. In practice, the limit is set by the file system on either end (most modern filesystems handle multi-terabyte files; older ones might have lower limits).