Skip to content
Français
Account: not signed in, sync available My learning
Select theme
Français

Transfer files with SFTP

By updated

Improve this page

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 put and download with get
  • 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.

ToolModeSpecialityWhen to use it
sftpInteractiveBrowsing session + multiple transfersExplore a remote server, several files in one session
scpOne-shotQuick copy of a file or directoryOne-off transfer, simple scripting
rsyncSynchronisationDelta, resume, controlled bandwidthRecurring backups, large volumes
tar + sshPipelineTrees with complex permissionsMigrations, 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.

Terminal window
sftp bob@server.example.com

You 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.

Terminal window
sftp -P 2222 bob@server.example.com

With 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.

Terminal window
sftp -i ~/.ssh/id_rsa_backup bob@server.example.com

Browsing 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 directory
sftp> lpwd # LOCAL current directory
sftp> ls # List the remote files
sftp> ls -la # With details and hidden files
sftp> lls # List the local files
sftp> cd /var/log/ # Change remote directory
sftp> lcd ~/Downloads/ # Change local directory
sftp> mkdir saves # Create a remote directory
sftp> rmdir old_saves # Remove an empty remote directory

Download 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.log

This 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.log

Download 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.gz

reget 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.conf

Upload 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 side
sftp> rm /tmp/useless-file.log # Delete on the remote side
sftp> chmod 640 /etc/app/app.conf # Change permissions
sftp> chown 1000 /home/bob/file # Change the owner
sftp> df -h # Disk space of the remote server
sftp> 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.

/home/bob/backup-sftp.txt
lcd /var/backup
cd /archives/linux-srv
put config-2026-04-09.tar.gz
put db-dump-2026-04-09.sql.gz
exit
Terminal window
sftp -b /home/bob/backup-sftp.txt bob@backup-server.example.com

Connect 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.

~/.ssh/config
Host backup-srv
HostName backup-server.example.com
User bob
Port 2222
IdentityFile ~/.ssh/id_rsa_backup
Terminal window
sftp backup-srv

Common 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.

SymptomProbable causeSolution
Connection refusedSSH port closed or service stoppedCheck ssh bob@server first
Permission denied (publickey)Key not authorised on the serverCheck ~/.ssh/authorized_keys on the server
File "/srv/missing.log" not found.Wrong remote pathUse ls and pwd to check the remote tree
dest open "...": Permission deniedThe connected account cannot write thereAim at an accessible directory, then move it with ssh and sudo
Warning: Permanently added ... to the list of known hosts.First access to the serverNormal, the key is stored in ~/.ssh/known_hosts
upload "...": path canonicalization failedParent of the target directory missing (put -r)Create the missing levels first with mkdir in SFTP
download "...": not a regular fileSymbolic link skipped by get -rFetch the link target separately, or switch to rsync
Slow transfer over a distant linkHigh latencyRaise the concurrent requests with sftp -R 128 (64 by default), or switch to rsync

Key points

  • sftp is the interactive mode of transfer over SSH, browse + transfer in a session, unlike scp, which acts one-shot.
  • The sftp> prompt offers the ls/lls, cd/lcd, get/put, reget/reput, mkdir, rm, chmod commands.
  • Uppercase -P for the SSH port (same convention as scp).
  • reget and reput resume an interrupted transfer.
  • get -r skips symbolic links while still ending with code 0: check the copy.
  • For scripts, use sftp -b batch-file.txt and 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

6 questions
6 min
70% to pass

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

Is this project useful to you?

The guides, courses, quizzes and labs stay free. If you use them regularly, you can contribute to their upkeep and development.

Become a supporting member (new tab) One-time support (new tab) Learn more

Follow the project on LinkedIn