sftp is the interactive mode of SSH file transfer. Where scp copies a file in one command, sftp opens a session in which you browse, list, create directories and transfer several files without disconnecting. It is the equivalent of a classic FTP client, but fully encrypted over SSH.
sftp is part of the OpenSSH client, targeted by the LFCS objective "Configure the OpenSSH server and client" of the Networking domain. Every measurement on this page was made on OpenSSH 9.6 (Ubuntu 24.04), 9.9 (AlmaLinux 10) and 10.0 (Debian 13), which behave the same way.
What you will learn
- Open an SFTP session and find your way in the local and remote directories
- List, browse and create directories on the remote and local sides
- Upload files with
putand download withget - Transfer a complete directory with
put -r/get -r - Use a custom SSH port with
-P - Resume an interrupted transfer with
reget/reput - Choose between SFTP, SCP and rsync depending on the situation
SFTP among Linux transfer tools
The four tools below all go through SSH and therefore use the same port and the same keys. What sets them apart is the interaction mode: sftp opens a session that you drive command by command, whereas scp, rsync and the tar/ssh pair run in a single invocation and then hand back control. Pick the row that matches what you do not know yet: if you do not know which files to fetch, you need a session.
| Tool | Mode | Speciality | When to use it |
|---|---|---|---|
| sftp | Interactive | Browsing session + multiple transfers | Explore a remote server, several files in one session |
| scp | One-shot | Quick copy of a file or directory | One-off transfer, simple scripting |
| rsync | Synchronisation | Delta, resume, controlled bandwidth | Recurring backups, large volumes |
tar + ssh | Pipeline | Trees with complex permissions | Migrations, custom archives |
SFTP is the right choice when:
- You need to explore a remote server before deciding what to transfer
- You transfer several files in different directories in one session
- You manage servers where only port 22 is open (no NFS nor Samba share)
- You automate transfers with tools that support the SFTP protocol
Open an SFTP session
The connection syntax is identical to that of ssh: user, at sign, host. Authentication plays out exactly the same way (public key, then password as a fallback), and the host key is checked in ~/.ssh/known_hosts. If ssh bob@server.example.com works, sftp will work too.
sftp bob@server.example.comYou land in an interactive prompt:
Connected to server.example.com.sftp>With an SSH port other than 22
Without this option, the client tries port 22 and fails with a Connection refused if the server listens elsewhere.
sftp -P 2222 bob@server.example.comWith a specific SSH key
Useful when you hold several private keys: -i designates the one to present, instead of letting the SSH agent try them all and getting cut off by the server after six attempts.
sftp -i ~/.ssh/id_rsa_backup bob@server.example.comBrowsing in an SFTP session
Once connected, you handle two simultaneous current directories, one remote, the other local, and each keeps its position for the whole session. Transfers always happen between these two points, which lets you chain several get without ever retyping a full path. You therefore have access to two spaces:
- The remote server, driven by the standard SFTP commands
- Your local machine, with commands prefixed by an
l(local)
Browsing commands
Remember the l prefix rule: the same command without a prefix acts on the server, with the prefix on your workstation.
sftp> pwd # REMOTE current directorysftp> lpwd # LOCAL current directorysftp> ls # List the remote filessftp> ls -la # With details and hidden filessftp> lls # List the local filessftp> cd /var/log/ # Change remote directorysftp> lcd ~/Downloads/ # Change local directorysftp> mkdir saves # Create a remote directorysftp> rmdir old_saves # Remove an empty remote directoryDownload files: get
get brings a file from the server to your workstation. The remote path can be absolute or relative to the current directory shown by pwd, and an optional second argument sets the local destination. Without that second argument, the file lands in the local current directory, the one returned by lpwd: it is the most frequent source of error when you think a download got lost.
sftp> get /var/log/nginx/access.logThis file is downloaded into the local current directory (visible with lpwd).
Download to a specific name or path
The local destination directory must already exist: sftp does not create it and answers open local "/tmp/doesnotexist/x.log": No such file or directory, with an exit code of 1 in batch mode.
sftp> get /var/log/nginx/access.log ~/logs/nginx-access-2026-04-09.logDownload several files with a glob
The pattern is expanded on the remote directory: the sftp client lists the server and fetches every matching file, your local shell plays no part. The star therefore does fetch all the rotated logs of the remote directory.
sftp> get /var/log/nginx/access.log.*Download a complete directory
The -r option walks the remote tree and creates the last level of the local path if it is missing, provided its parent exists (otherwise mkdir /tmp/doesnotexist2/www: No such file or directory). It does not follow symbolic links: each one is skipped with download "/srv/www/link.html": not a regular file, and the command still ends with exit code 0. A /var/www/html full of shortcuts therefore arrives incomplete without a script noticing.
sftp> get -r /var/www/html/ ~/backup/html/Resume an interrupted download
On a multi-gigabyte archive cut by a VPN drop, running get again would start over from zero.
sftp> reget /var/backup/full-dump.tar.gzreget resumes where the transfer stopped instead of starting over from zero.
Upload files: put
put is the mirror of get: it sends a file from your workstation to the server. Write permissions apply to the account you connected with; sending into /etc/app/ therefore assumes that bob can write there, because an SFTP session offers no equivalent of sudo. The refusal shows up as dest open "/etc/app/app.conf": Permission denied. Aim at an accessible directory instead, then move the file through a regular ssh session.
sftp> put ~/projects/app.conf /etc/app/app.confUpload several files
Here the pattern is expanded on the local side by the sftp client itself, in the directory set by lcd: no shell is involved, which explains why the same line also works in a batch file.
sftp> put *.conf /etc/app/Upload a complete directory
The last level of the remote path is created if it is missing, but its parent directory must exist. Otherwise sftp refuses with two lines, realpath /srv/x/y/z: No such file then upload "/srv/x/y/z": path canonicalization failed: create the missing levels first with mkdir from the session.
sftp> put -r ~/dev/my-project/ /var/www/html/my-project/Resume an interrupted upload
reput does for sending what reget does for receiving: it completes the partial remote file instead of overwriting it.
sftp> reput ~/backup/full-dump.tar.gz /backup/File management commands in SFTP
An SFTP session is not limited to transfers: it exposes a subset of the server's file operations, which saves opening a second ssh connection for a simple rename. Two details to know: chown expects a numeric ID, not an account name (chown bob file answers You must supply a numeric argument to the chown command.), and df is only available if the server implements the statvfs@openssh.com extension (OpenSSH does, not every SFTP server).
sftp> rename old.conf new.conf # Rename on the remote sidesftp> rm /tmp/useless-file.log # Delete on the remote sidesftp> chmod 640 /etc/app/app.conf # Change permissionssftp> chown 1000 /home/bob/file # Change the ownersftp> df -h # Disk space of the remote serversftp> exit # Quit the session (or Ctrl+D)Automate SFTP transfers with a batch
For scripts, sftp accepts a command file through -b: each line is run as if you had typed it at the prompt. This mode stops the session as soon as a command fails and returns exit code 1, which is exactly the behaviour expected from a backup script: an rm on a missing file prints remote delete ...: No such file or directory and the following lines do not run. To tolerate one specific failure, prefix the line with a dash (-rm old.tar.gz): the message is still printed, but the session goes on. The command file accepts no password: authentication must be non-interactive.
lcd /var/backupcd /archives/linux-srvput config-2026-04-09.tar.gzput db-dump-2026-04-09.sql.gzexitsftp -b /home/bob/backup-sftp.txt bob@backup-server.example.comConnect with an SSH configuration file
sftp reads the same ~/.ssh/config file as ssh and scp. An alias that groups the host, the account, the port and the key there spares you from repeating -P and -i at each connection, and guarantees that the backup script and the manual session use strictly the same parameters.
Host backup-srv HostName backup-server.example.com User bob Port 2222 IdentityFile ~/.ssh/id_rsa_backupsftp backup-srvCommon troubleshooting
Almost all SFTP failures are actually SSH failures: the transfer protocol only comes into play once the connection is established. The first reflex is therefore to test ssh to the same host with the same options; if ssh works and sftp fails, the problem lies in the server's sftp subsystem or in the remote path.
| Symptom | Probable cause | Solution |
|---|---|---|
Connection refused | SSH port closed or service stopped | Check ssh bob@server first |
Permission denied (publickey) | Key not authorised on the server | Check ~/.ssh/authorized_keys on the server |
File "/srv/missing.log" not found. | Wrong remote path | Use ls and pwd to check the remote tree |
dest open "...": Permission denied | The connected account cannot write there | Aim at an accessible directory, then move it with ssh and sudo |
Warning: Permanently added ... to the list of known hosts. | First access to the server | Normal, the key is stored in ~/.ssh/known_hosts |
upload "...": path canonicalization failed | Parent of the target directory missing (put -r) | Create the missing levels first with mkdir in SFTP |
download "...": not a regular file | Symbolic link skipped by get -r | Fetch the link target separately, or switch to rsync |
| Slow transfer over a distant link | High latency | Raise the concurrent requests with sftp -R 128 (64 by default), or switch to rsync |
Key points
sftpis the interactive mode of transfer over SSH, browse + transfer in a session, unlikescp, which acts one-shot.- The
sftp>prompt offers thels/lls,cd/lcd,get/put,reget/reput,mkdir,rm,chmodcommands. - Uppercase
-Pfor the SSH port (same convention asscp). regetandreputresume an interrupted transfer.get -rskips symbolic links while still ending with code 0: check the copy.- For scripts, use
sftp -b batch-file.txtand key authentication. - For large recurring backups, rsync remains more efficient (delta, controlled bandwidth).
Knowledge check
Check that the essentials of this guide stuck. The questions cover only what has just been explained here.
Knowledge check
Check what you have learned with this interactive quiz
How it works
- The timer starts when you click Start
- Multiple choice, true/false and short answer questions
- You can move between questions
- Detailed results are shown at the end
Starts the quiz and the timer
Review
(0/0)Score by domain
A domain groups several guides and gets several questions, so its score is more reliable than a per-topic score, which often rests on a single question.
Summary
Strengths
No topic passed at 80% on at least two questions yet.
Weak areas
No topic below the pass mark.
Recommended next
Hints before you try again?
Continue the course: rsync: synchronise and back up files
A new full quiz with random questions
Work again only on the questions you missed