Networking · FTP

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.

Updated 2026-09-08
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.

Figure 1. The whole article on one page. Every branch is a section below; fold what you know, open what you do not.

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
Figure 2. One file. Steps 1 to 9 and 11 are on the control connection. Step 10 is a second TCP connection that exists only for this file. The next file needs a new PASV and a new data connection.

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.

In the wild
  • 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
Figure 3. The two modes differ only in the direction of the data connection. Active mode asks the client's network to accept an incoming connection, which NAT and firewalls refuse by default.

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.

ActivePassive
CommandPORT h1,h2,h3,h4,p1,p2PASV or EPSV
Who opens the data connectionThe server, from port 20The client, to a port the server chose
Client behind NATBreaksWorks
Server firewall must allowOutbound from port 20Inbound on 21 plus a range of high ports
Default in modern clientsNoYes

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.

In the wild
  • 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.
Watch out

"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:

CommandDoesTypical reply
USER, PASSLog in. "anonymous" with an email as password is the public convention.331, then 230
PWD, CWD, CDUPWhere am I, change directory, go up.257, 250
LIST, NLST, MLSDDirectory listing over a data connection: human format, names only, machine format.150 then 226
TYPE A, TYPE IASCII or binary transfer mode. Next section.200
PASV, EPSV, PORTSet up the next data connection.227, 229, 200
RETR, STORDownload, upload.150 then 226
SIZE, MDTMFile size, modification time.213
DELE, RNFR + RNTO, MKD, RMDDelete, rename, make and remove directory.250, 257
RESTResume from a byte offset before RETR or STOR.350
QUITClose 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.

In the wild
  • curl speaks FTP natively and -v shows the transcript above; lftp is the scriptable client for mirroring and resuming.
  • FileZilla is the graphical client most people have used; its log window is the same transcript.
  • REST is 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.

In the wild
  • 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.

FTPFTPSSFTPHTTPS
IsThe originalFTP wrapped in TLSA file protocol inside SSH. Not FTP at allFiles over HTTP
Port21 plus data ports21 (explicit) or 990 (implicit), plus data ports22443
ConnectionsTwo per transferTwo per transfer, both encryptedOneOne
EncryptedNoYesYesYes
Through NAT and firewallsPainfulWorse: helpers cannot read PASVEasyEasy
AuthenticationPasswordPassword, or client certificatePassword or SSH keyAnything HTTP supports
Use it whenNever on the internetA partner insists on itYou need a file server for humans and scriptsYou 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.

In the wild
  • 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@host and scp use it, and rsync over 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.
Watch out

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.

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.

In the wild
  • 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.
  • EPSV is 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_port and pasv_max_port, and a cloud security group with the same range, are the usual setup.
  • A Linux NAT with nf_conntrack_ftp can 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.