FTP: the protocol with two connections
How FTP splits commands and data across two TCP connections, why active mode breaks behind NAT and passive mode fixes it, a session on the wire, the ASCII trap, why plain FTP is fading, and where it still lives.
On this page
FTP is older than TCP/IP itself, and it shows. It was designed for a world where every machine had a public address and nobody was listening in. It opens a second connection for every file, in a direction that firewalls hate, and it sends your password as text. It is also still everywhere: in banks, in hosting panels, in the boot process of every network switch. Knowing it explains a family of protocol designs, and a family of firewall problems.
The map
Read this first when short on time. Every branch is a section below.
Two connections: one for talking, one for bytes
Every other protocol on this site uses one TCP connection and sends commands and data through it. FTP uses two. The control connection carries commands and replies as text and stays open for the whole session. Every directory listing and every file goes over a separate data connection, opened for that transfer and closed when it ends.
sequenceDiagram autonumber participant C as Client participant S as Server Note over C,S: control connection, port 21, open all session C->>S: USER alice S-->>C: 331 Password required C->>S: PASS **** S-->>C: 230 Logged in C->>S: PASV S-->>C: 227 Entering passive mode (h1,h2,h3,h4,p1,p2) Note over C,S: data connection, new port, for this file only C->>S: RETR report.pdf S-->>C: 150 Opening data connection S-->>C: (bytes of report.pdf on the data connection) S-->>C: 226 Transfer complete
The reason is historical. FTP was specified in 1971 for the ARPANET, before TCP existed, when a "connection" was a scarce, fiddly thing and keeping the command channel clear of gigabytes of data was a real design goal. It let the client abort a transfer by sending a command on the control connection while the data connection was busy, and it let a third machine tell two servers to transfer a file between them directly. Nobody uses that second feature, but the two-connection shape remains, and it is the source of everything awkward about FTP.
The control connection is a plain text conversation on port 21. The client sends a command, three or four letters and maybe an argument, ending in a line break. The server replies with a three-digit code and a message. The digits mean the same as HTTP's: 1xx means "started, wait for more", 2xx means done, 3xx means "fine, now send the next thing", 4xx is a temporary failure, 5xx is a permanent one. The HTTP article's status codes borrowed this scheme directly.
- Wireshark shows an FTP session as one long TCP stream on port 21 and a series of short ones on other ports; the "Follow TCP stream" view of the control connection is readable as a transcript.
- Every FTP client hides the two connections completely, which is why users are surprised when a firewall lets them log in but not list a directory.
- SMTP and POP3, from the same era, use the same text-command and three-digit-reply style but on one connection.
- Control connection
- The TCP connection on port 21 carrying commands and replies for the whole session.
- Data connection
- A separate TCP connection opened per transfer, carrying one listing or one file.
Active and passive: who connects to whom
The data connection has to be opened by someone. FTP's original answer was the server. That made sense in 1971 and breaks in every home and office today.
flowchart TD
subgraph A["Active mode"]
direction TB
A1["Client: PORT my-address,my-port"] --> A2["Server connects from port 20 to the client"]
A2 --> A3["Client's firewall or NAT: unexpected inbound connection, dropped"]
end
subgraph P["Passive mode"]
direction TB
P1["Client: PASV"] --> P2["Server: 227 connect to me on port 51000"]
P2 --> P3["Client connects outward, as usual. Works through NAT."]
end
A ~~~ P
In active mode the client sends a PORT command with its own address and a port it is listening on, and the server connects back to it, from port 20. The client has become a server for a moment. Behind a home router that fails immediately: the router has no NAT mapping for an inbound connection, as the packet journey explains, so the server's connection is dropped and the transfer hangs at "150 Opening data connection". The address the client puts in PORT is its private one anyway, which the server cannot reach.
In passive mode the client sends PASV and the server replies with an address and a port it has opened. The client connects outward to that port, like any normal client. NAT and firewalls on the client side are happy. The burden moves to the server, which must accept connections on a range of high ports in addition to 21, and must put its public address in the reply, which servers behind NAT get wrong unless configured. EPSV is the same idea for IPv6, replying with just a port.
| Active | Passive | |
|---|---|---|
| Command | PORT h1,h2,h3,h4,p1,p2 | PASV or EPSV |
| Who opens the data connection | The server, from port 20 | The client, to a port the server chose |
| Client behind NAT | Breaks | Works |
| Server firewall must allow | Outbound from port 20 | Inbound on 21 plus a range of high ports |
| Default in modern clients | No | Yes |
The port in these commands is written as two numbers, p1,p2, meaning p1 × 256 + p2. A reply of 227 Entering Passive Mode (203,0,113,7,199,72) means connect to 203.0.113.7 on port 199 × 256 + 72 = 51016. Firewalls that understand FTP read this reply as it passes and open that port for the coming connection; that is the "FTP helper" or "ALG" in a router's settings, and it is also why FTP over TLS breaks it, since the reply is encrypted and the helper cannot read it.
- vsftpd and ProFTPD have settings for the passive port range (
pasv_min_port,pasv_max_port) and the public address to advertise; both must match the firewall rules or nothing works. - AWS Transfer Family, the managed FTP service, requires a fixed passive port range in the security group for exactly this reason.
- Linux conntrack has
nf_conntrack_ftp, a module that reads control connections and opens the data port automatically; it is why FTP through a Linux NAT box often just works.
"I can log in but ls hangs" is always the data connection. Switch the client to passive mode. If it is already passive, the server is advertising a private address or its high ports are blocked.
- Active mode
- The server opens the data connection to the client. Fails behind NAT.
- Passive mode
- The client opens the data connection to a port the server announces. Works behind NAT.
- ALG
- Application layer gateway: a firewall feature that reads FTP replies and opens the ports they mention.
A session on the wire
Here is a complete session, exactly as it appears on the control connection, downloading one file with curl. Arrows mark direction; they are not on the wire.
$ curl -v ftp://ftp.example.com/pub/report.pdf -o report.pdf
< 220 Welcome to ftp.example.com
> USER anonymous
< 331 Please specify the password.
> PASS ftp@example.com
< 230 Login successful.
> PWD
< 257 "/" is the current directory
> CWD pub
< 250 Directory successfully changed.
> EPSV
< 229 Entering Extended Passive Mode (|||51016|)
* Connecting to 203.0.113.7 port 51016
> TYPE I
< 200 Switching to Binary mode.
> SIZE report.pdf
< 213 482911
> RETR report.pdf
< 150 Opening BINARY mode data connection for report.pdf (482911 bytes).
* ...482911 bytes received on the data connection
< 226 Transfer complete.
> QUIT
< 221 Goodbye.
The commands worth knowing:
| Command | Does | Typical reply |
|---|---|---|
USER, PASS | Log in. "anonymous" with an email as password is the public convention. | 331, then 230 |
PWD, CWD, CDUP | Where am I, change directory, go up. | 257, 250 |
LIST, NLST, MLSD | Directory listing over a data connection: human format, names only, machine format. | 150 then 226 |
TYPE A, TYPE I | ASCII or binary transfer mode. Next section. | 200 |
PASV, EPSV, PORT | Set up the next data connection. | 227, 229, 200 |
RETR, STOR | Download, upload. | 150 then 226 |
SIZE, MDTM | File size, modification time. | 213 |
DELE, RNFR + RNTO, MKD, RMD | Delete, rename, make and remove directory. | 250, 257 |
REST | Resume from a byte offset before RETR or STOR. | 350 |
QUIT | Close the session. | 221 |
Notice that every transfer is three steps: set up the data connection, send the transfer command, wait for 150 and then 226. A client uploading a hundred small files does a hundred PASV and a hundred TCP handshakes, plus a hundred TIME-WAIT sockets, as the TCP article describes. This is why FTP is slow for many small files and fine for a few large ones.
curlspeaks FTP natively and-vshows the transcript above;lftpis the scriptable client for mirroring and resuming.- FileZilla is the graphical client most people have used; its log window is the same transcript.
RESTis what "resume download" means; it is why interrupted large transfers over FTP could be continued long before HTTP had range requests.
ASCII versus binary: the corrupted file
FTP has two transfer types, and choosing the wrong one silently corrupts files. It is the most common FTP mistake of the past thirty years.
ASCII mode (TYPE A) is for text. The sender converts the file's line endings to a standard form and the receiver converts them to its own, so a text file from a Windows machine (\r\n) lands on a Unix machine with plain \n. In 1980 that was helpful. Applied to a zip file, an image or a program, it rewrites every byte that happens to look like a line ending, and the file is destroyed with no error.
Binary mode (TYPE I, for "image") transfers bytes exactly. Every modern client uses it by default for everything, and text editors handle line endings themselves. There is no reason to send TYPE A today, and the only thing to know is that an old server or script that defaults to ASCII is why your download does not open.
- The corrupted zip that is a few bytes larger than the original, downloaded through an old client, is ASCII mode at work.
- Mainframe transfers still use ASCII mode deliberately, because EBCDIC to ASCII conversion of text files is part of the transfer.
- TYPE A
- ASCII mode: line endings converted in transit. Text only.
- TYPE I
- Image, meaning binary mode: bytes unchanged. Use it for everything.
No encryption, and the three things that replaced it
Plain FTP sends the username, the password and every file as readable text. Anyone on the path, a coffee shop Wi-Fi, an ISP, a compromised router, can read them and can alter the files in transit. That was acceptable on a network of trusted universities and is not acceptable anywhere now. Three replacements exist, and their names are confusingly similar.
| FTP | FTPS | SFTP | HTTPS | |
|---|---|---|---|---|
| Is | The original | FTP wrapped in TLS | A file protocol inside SSH. Not FTP at all | Files over HTTP |
| Port | 21 plus data ports | 21 (explicit) or 990 (implicit), plus data ports | 22 | 443 |
| Connections | Two per transfer | Two per transfer, both encrypted | One | One |
| Encrypted | No | Yes | Yes | Yes |
| Through NAT and firewalls | Painful | Worse: helpers cannot read PASV | Easy | Easy |
| Authentication | Password | Password, or client certificate | Password or SSH key | Anything HTTP supports |
| Use it when | Never on the internet | A partner insists on it | You need a file server for humans and scripts | You are building something new |
FTPS is FTP with TLS. In explicit mode the client connects to port 21 as usual and sends AUTH TLS, and the control connection is upgraded, the same trick as STARTTLS in email. Data connections are then encrypted too. In implicit mode, port 990 is TLS from the first byte. Either way it is still two connections per transfer, and now the firewall helper that used to read PASV replies is blind, so the passive port range must be opened by hand. FTPS exists mostly because organisations with FTP scripts wanted encryption without changing the scripts.
SFTP shares three letters and nothing else. It is a file access protocol that runs as a subsystem inside an SSH connection: one TCP connection on port 22, encrypted from the start, authenticated with a password or an SSH key, with commands for reading, writing, listing and renaming that look like a filesystem API rather than FTP's text conversation. It goes through NAT because it is one outbound connection. It is the usual answer when someone asks for "an FTP server" today, and every SSH server provides it.
And for anything new, HTTPS already does file upload and download with range requests, resumable uploads, and every authentication scheme, on a port that is open everywhere, which is why object stores like S3 are HTTP APIs and not FTP servers.
- Chrome and Firefox removed support for
ftp://URLs in 2021, mostly because it could not be made secure. - OpenSSH ships the SFTP server on every Linux box;
sftp user@hostandscpuse it, andrsyncover SSH does the same job with delta transfers. - Banks and payment networks still exchange batch files by FTPS or SFTP on a schedule, because the systems on both ends were built around dropping files in a folder.
SFTP is not "secure FTP", and FTPS is not SFTP. A firewall rule for one does nothing for the other, and a client for one cannot talk to a server for the other. When someone says "FTP over SSL" they mean FTPS; when they say "FTP over SSH" they mean SFTP, which is not FTP.
- FTPS
- FTP with TLS on the control and data connections. Explicit (AUTH TLS on 21) or implicit (port 990).
- SFTP
- SSH File Transfer Protocol: file operations inside an SSH session on port 22. Unrelated to FTP.
Where FTP still lives, and its tiny cousin TFTP
FTP is not gone, because a lot of software was built when it was the only option and still works.
- Scheduled file exchange between companies: banks, insurers, logistics, government. A file is dropped in a folder at 2 a.m. and picked up at 3. Usually FTPS or SFTP now, but the workflow is FTP's.
- Shared web hosting: the FTP account in a cPanel panel is still how many small sites are deployed.
- Devices: network switches, cameras, printers and industrial controllers often have an FTP server built in for firmware upload and log retrieval, because it was small and everyone had a client.
- Public archives: some software mirrors and scientific datasets kept FTP alongside HTTP for decades; most have finally turned it off.
TFTP, the Trivial File Transfer Protocol, is a different and much smaller thing that shares the name. It runs on UDP port 69, has no login, no directory listing and no security, and moves a file in 512-byte blocks each acknowledged before the next is sent. It exists for one job: a device that has just powered on, has no operating system yet and a network stack of a few kilobytes, needs to fetch its boot image. That is PXE boot: the machine gets an address from DHCP, the DHCP reply names a TFTP server and a file, and the firmware downloads it block by block. The UDP article explains why a stack that small could only afford UDP.
- Every data centre's server provisioning starts with PXE and TFTP before the real installer arrives over HTTP.
- Cisco and Juniper devices load configurations and OS images over TFTP;
copy tftp: flash:is one of the first commands network engineers learn. - Phones on a desk, IP telephony handsets, fetch their configuration from a TFTP server named by DHCP when they boot.
- TFTP
- Trivial File Transfer Protocol: UDP port 69, no login, 512-byte blocks, used to boot devices.
- PXE
- Preboot execution environment: firmware that gets an address from DHCP and a boot image from TFTP.
Recap
- FTP uses two TCP connections: a control connection on port 21 for text commands and three-digit replies, and a fresh data connection for every listing and file.
- Reply codes follow the same first-digit scheme HTTP later borrowed: 1 wait, 2 done, 3 continue, 4 temporary failure, 5 permanent failure.
- Active mode has the server connect back to the client, which NAT and firewalls block. Passive mode has the client connect to a port the server announces. Use passive.
- Passive servers need a high port range open and their public address configured; firewall helpers read PASV replies to open ports, and cannot once TLS hides them.
- "Login works, listing hangs" is always the data connection.
- Every transfer is PASV, the command, 150, bytes, 226: a handshake per file, so many small files are slow.
- Always
TYPE I. ASCII mode rewrites line endings and silently corrupts binaries. - Plain FTP sends passwords and files in the clear. FTPS wraps it in TLS and keeps the firewall pain. SFTP is a different protocol inside SSH on one connection and is the normal replacement. New systems use HTTPS.
- FTP survives in scheduled business file exchange, shared hosting, and embedded devices. Browsers dropped it in 2021.
- TFTP is a separate UDP protocol on port 69 with no login, used by PXE to boot machines and network gear.
Questions
Try answering each one out loud before opening it. Lead with the one-line answer, then a couple of points, then one extra detail.
Why does FTP use two connections, and what does each carry?
A control connection on port 21 carries text commands and three-digit replies for the whole session, and a separate data connection is opened for each listing or file transfer and closed afterwards; the split dates from 1971, when keeping the command channel free of bulk data and being able to abort a transfer mid-way were design goals.
- Every transfer costs a new TCP handshake, so many small files are slow.
- The data connection is the part that breaks behind firewalls.
The reply-code scheme, 2xx success, 4xx temporary, 5xx permanent, is where HTTP's status codes came from.
Active versus passive mode: what is the difference and which should you use?
In active mode the client sends PORT and the server connects back to it from port 20; in passive mode the client sends PASV and connects outward to a port the server announces. Use passive: active fails behind NAT because the inbound connection has no mapping and the advertised address is private.
- Passive moves the burden to the server, which must open a high port range and advertise its public address.
EPSVis the IPv6-friendly form that returns only a port.
Every modern client defaults to passive, and "login works but listing hangs" means a data connection problem.
Decode 227 Entering Passive Mode (203,0,113,7,199,72).
Connect the data connection to 203.0.113.7 on port 199 × 256 + 72 = 51016.
- The first four numbers are the address, the last two encode the port in two bytes.
- A server behind NAT that puts its private address here breaks every client.
Firewall helpers parse exactly this line to open the port in time, which is why FTPS, which encrypts it, defeats them.
What does a firewall need to allow for a passive FTP server?
Inbound TCP on port 21 and on the configured passive port range, and the server must be told its public address to advertise; without a fixed range the data ports are unpredictable and cannot be opened.
- vsftpd's
pasv_min_portandpasv_max_port, and a cloud security group with the same range, are the usual setup. - A Linux NAT with
nf_conntrack_ftpcan open ports dynamically by reading the control connection, for plain FTP only.
Active mode instead needs the client's side to accept inbound connections, which is why it is dead.
Why did a downloaded zip file end up corrupted and slightly larger?
It was transferred in ASCII mode (TYPE A), which converts line endings and so rewrites every byte sequence that looks like one; binary files must be sent with TYPE I, which modern clients use by default.
- ASCII mode existed to convert text between systems with different line endings.
- The only legitimate use today is mainframe text with EBCDIC conversion.
There is no error; the transfer completes with 226 and the file is simply wrong.
What is wrong with plain FTP on the internet?
The username, password and every file cross the network as readable text, so anyone on the path can capture the credentials and read or alter the files; it was designed for a trusted network of research machines.
- Browsers removed
ftp://support in 2021 partly for this reason. - The replacements are FTPS, SFTP, or simply HTTPS.
Anonymous FTP for public downloads was the one case where the lack of secrecy did not matter, and even that has moved to HTTPS.
FTPS versus SFTP?
FTPS is FTP wrapped in TLS, still two connections per transfer on ports 21 or 990 plus a data range; SFTP is a completely different file protocol that runs inside an SSH session on port 22 over one connection, and it is the usual replacement.
- FTPS keeps FTP's firewall problems and makes them worse because helpers cannot read encrypted PASV replies.
- SFTP authenticates with SSH keys and goes through NAT like any outbound connection.
A firewall rule or client for one does nothing for the other.
How does explicit FTPS start?
The client connects to port 21 in plain text and sends AUTH TLS; the server agrees, both sides perform a TLS handshake on the existing connection, and everything after, including data connections, is encrypted.
- Implicit FTPS on port 990 starts TLS before any command, and is older and less common.
- This is the same upgrade pattern as STARTTLS in SMTP.
Explicit mode lets one port serve both encrypted and plain sessions, which is also its weakness if the server allows the plain ones.
Why is FTP slow for many small files?
Every file needs a PASV exchange, a new TCP handshake for the data connection, the transfer command, and the 150 and 226 replies, so several round trips and a socket per file; a thousand small files means a thousand handshakes and a thousand TIME-WAIT sockets.
- Large files amortise this and transfer at line speed.
- SFTP and HTTP pipeline operations over one connection.
Archiving the files first and sending one tarball is the classic workaround.
What is TFTP and why does it exist?
A separate, tiny file transfer protocol on UDP port 69 with no login, no listing and 512-byte acknowledged blocks, built so a device with only a few kilobytes of firmware can fetch its boot image; PXE boot uses DHCP to name the TFTP server and file.
- It shares almost nothing with FTP besides the name.
- Network switches, IP phones and data centre servers all boot this way.
Once the real operating system is running, the rest of the installation usually continues over HTTP.
Where is FTP still used, and what would you recommend instead?
Scheduled business file exchange, shared web hosting uploads and embedded device firmware, because the systems on both ends were built around it; for anything new, SFTP for a file server that people and scripts use, and HTTPS with an object store for applications.
- Partners who insist on FTP can usually be moved to FTPS or SFTP without changing their workflow.
- S3 and its clones are HTTP APIs precisely because HTTPS already does files well.
AWS even sells a managed SFTP and FTPS front end to S3 for partners who cannot change.