1. What even is SFTP?
SFTP stands for SSH File Transfer Protocol. Despite the name similarity, it has almost nothing to do with the old FTP (File Transfer Protocol) — it's an entirely different protocol built on top of SSH (Secure Shell).
At its core, SFTP lets you securely transfer files between two computers over a network. When you need to drop a file on a remote server, pull logs off a machine, or automate moving data between systems — SFTP is one of the most common tools you'll reach for.
2. SFTP vs FTP vs FTPS — the confusion, cleared up
These three names cause a lot of confusion for beginners. Here's a quick breakdown:

3. How SFTP works under the hood
SFTP runs as a subsystem of SSH. When you initiate an SFTP session, your SSH client negotiates an encrypted tunnel, and then launches the SFTP subsystem on the remote machine. All file operations — read, write, rename, delete — happen inside that tunnel.
Here's the rough flow:
- Client opens a TCP connection to the server on port 22.
- SSH handshake happens — server identity is verified, keys/passwords are exchanged.
- An encrypted session is established.
- The SFTP subsystem is started on the server side.
- Client and server exchange SFTP protocol messages (open file, read, write, close, etc.) over the encrypted channel.
Because it works on top of SSH, SFTP automatically gets everything SSH gives you: strong encryption, host verification, and support for public-key authentication.
4. Your first SFTP connection (CLI)
On macOS and Linux, the sftp client ships with OpenSSH. On Windows, it's available via PowerShell or WSL. Connecting is straightforward
For example:
sftp myUserName@sftp.example.com
You'll be prompted for a password (or it will authenticate silently with your SSH key). Once connected, you'll land in an interactive shell:
Connected to sftp.example.com.
sftp> _
You can also specify a custom port if the server isn't on 22:
sftp -P 2222 myUserName@sftp.example.com
5. Common SFTP commands you'll actually use
Inside the interactive SFTP shell, you navigate the remote file system and your local file system at the same time. Commands prefixed with 'l' operate locally; others operate remotely.
6. Key-based authentication
Typing a password every time gets old fast, and passwords are weaker than cryptographic keys. The proper way to authenticate to SFTP (and SSH in general) is with an SSH key pair.
Step 1 — Generate a key pair on your machine:
ssh-keygen -t ed25519 -C "your@email.com"
This creates two files: ~/.ssh/id_ed25519 (private key — never share this) and ~/.ssh/id_ed25519.pub (public key — safe to distribute).
Step 2 — Copy your public key to the server:
ssh-copy-id myUserName@sftp.example.com
This appends your public key to ~/.ssh/authorized_keys on the server. Now connecting will work without a password prompt.
Important: Set correct permissions. Your ~/.ssh directory should be 700 and your private key file should be 600. SSH will refuse to use keys with overly permissive permissions
7. known_hosts — your silent security guard
Every time you connect to an SSH/SFTP server for the first time, your client saves the server's host public key to a local file: ~/.ssh/known_hosts. On subsequent connections, SSH checks the server's fingerprint against this record. If they match, the connection proceeds silently. If they don't, SSH throws a loud warning and refuses to connect.
This mechanism protects you against man-in-the-middle (MITM) attacks — where someone intercepts your connection and impersonates the server. Without it, an attacker on the same network could silently intercept your file transfers and credentials.
What a known_hosts entry looks like:
# ~/.ssh/known_hosts
sftp.example.com ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAI...
Each line stores: the hostname/IP, the key algorithm, and the base64-encoded public key. You never need to edit this file by hand — SSH manages it automatically.
What the warning looks like (and what to do)
If a server's fingerprint changes — perhaps the server was rebuilt, or the SSH keys were rotated — you'll see this:
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@ WARNING: REMOTE HOST @
@ IDENTIFICATION HAS CHANGED! @
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY!
Offending key for IP in /Users/you/.ssh/known_hosts:12
Do NOT blindly clear the entry and reconnect. First verify out-of-band (ask the server admin, check the cloud console, or use a trusted internal tool) that the server's keys legitimately changed. Only once you've confirmed it's safe should you remove the stale entry:
ssh-keygen -R sftp.example.com
Then reconnect and SSH will prompt you to confirm and save the new fingerprint.
8. Using SFTP in code
For automation or application-level file transfers, you don't use the CLI — you use a library. Here are the most common picks by language:
Node.js — using ssh2-sftp-client:
import Client from 'ssh2-sftp-client';
const sftp = new Client();
await sftp.connect({
host: 'sftp.example.com',
port: 22,
username: 'myUserName',
privateKey: require('fs').readFileSync('/home/you/.ssh/id_ed25519'),
});
await sftp.put('./report.csv', '/remote/reports/report.csv');
await sftp.end();
Python — using paramiko:
import paramiko
transport = paramiko.Transport(('sftp.example.com', 22))
transport.connect(username='myUserName',
pkey=paramiko.Ed25519Key.from_private_key_file('/home/you/.ssh/id_ed25519'))
sftp = paramiko.SFTPClient.from_transport(transport)
sftp.put('./report.csv', '/remote/reports/report.csv')
sftp.close()
transport.close()
Java — using JSch:
JSch jsch = new JSch();
jsch.addIdentity("/home/you/.ssh/id_ed25519");
jsch.setKnownHosts("/home/you/.ssh/known_hosts");
Session session = jsch.getSession("myUserName", "sftp.example.com", 22);
session.connect();
ChannelSftp channelSftp = (ChannelSftp) session.openChannel("sftp");
channelSftp.connect();
channelSftp.put("./report.csv", "/remote/reports/report.csv");
channelSftp.exit();
session.disconnect();
9. Things that trip beginners up
- Port 22 blocked by a firewall. If you can't connect, check if port 22 is open. Ask your sysadmin or check with: telnet hostname 22
- "Host key verification failed". This happens when the server's fingerprint isn't in your ~/.ssh/known_hosts. Run: ssh-keyscan hostname >> ~/.ssh/known_hosts
- Permission denied despite correct credentials. The server's sshd_config may restrict SFTP access, or the authorized_keys file has wrong permissions (chmod 600 ~/.ssh/authorized_keys on the server).
- Paths are confusing. The remote path is relative to the user's home directory by default. Use pwd inside the SFTP shell to confirm where you are.
- Large file transfers timing out. For big files in scripts, increase the ServerAliveInterval in your SSH config, or use rsync over SSH which supports resuming.
Wrapping up
SFTP isn't glamorous, but it shows up constantly in real-world systems — automated deployments, data pipelines, legacy integrations, and secure log collection. The essentials are simple: it's SSH-based, it's encrypted, and port 22 is all you need.
Start with the CLI to get a feel for navigating remote filesystems, switch to key-based auth as soon as possible, and reach for a library when you need to automate. Once you've done it a few times it becomes second nature.

Top comments (0)