Port 21 is the FTP control channel. It carries commands and responses only — no file data ever crosses it. The files themselves move over a completely separate connection, and that split between control and data is the source of nearly every problem FTP has ever caused.
It is also why FTP is the protocol most likely to work perfectly on your machine and fail entirely from a container, behind a load balancer, or through a corporate firewall. The design made sense in 1971. It has aged into a liability.
Table of contents
- Two connections, not one
- Active and passive mode
- The credentials problem
- What to use instead
- Debugging an FTP connection
- Why deploys stopped using it
- How this fits the rest of the stack
- FAQ
Two connections, not one
Almost every other protocol you use opens one connection and does everything over it. FTP opens two.
- The control connection, on port 21. The client connects here and stays connected for the whole session. Commands like USER, PASS, LIST, and RETR go over this channel, along with the numeric response codes.
- The data connection, on a separate port. Every directory listing and every file transfer opens a brand new connection, transfers, and closes. A session that downloads ten files opens ten data connections.
So port 21 is where you log in and issue commands. Port 20 — the one usually mentioned alongside it — is the server’s source port for data in active mode only, which is a mode almost nobody uses any more.
That second connection is the whole problem. A firewall can easily allow traffic to a known port. It cannot easily allow traffic to a port number that is negotiated at runtime, per transfer, inside the payload of another connection.
Active and passive mode
The two modes differ in who opens the data connection, and that determines whose firewall breaks.
Active mode — the client tells the server which port to connect back on, and the server initiates the data connection to the client. This means the server makes an inbound connection to the client, which every client-side firewall and every NAT router blocks by default. Active mode is effectively dead on the modern internet.
Passive mode — the client sends PASV, the server replies with a port number, and the client opens the data connection to the server. All connections are outbound from the client, which firewalls and NAT handle fine. This is what every FTP client defaults to.
Passive mode shifts the problem to the server side. The server must have a range of ports open for inbound data connections, and it must advertise an address the client can actually reach. A server behind NAT that advertises its internal address in the PASV response produces the classic symptom: you log in successfully, and then directory listings hang forever.
That symptom — login works, listing hangs — is diagnostic. It means the control connection is fine and the data connection is not, which is a passive-mode configuration problem essentially every time.
The credentials problem
Plain FTP sends the username and password in clear text over port 21. Not hashed, not obscured — the literal string, readable by anything on the path.
This was acceptable when FTP was designed for a research network of mutually trusting institutions. It is not acceptable now, and the practical consequence is that FTP credentials leak on any untrusted network. Public wifi is the obvious case, but so is any shared hosting environment where you do not control the network path.
File contents are equally unencrypted. Anything transferred over plain FTP is readable in transit, including the configuration files and database dumps people most often move this way.
There is no configuration that fixes this. Plain FTP has no encryption to enable, which is why the replacements are separate protocols rather than options.
What to use instead
Three options, and they are not equivalent despite the similar names:
- SFTP (port 22) — SSH File Transfer Protocol. Not FTP at all; it is a subsystem of SSH. One connection, fully encrypted, works through firewalls without special configuration because it is just SSH. This is the right default.
- FTPS (port 21 or 990) — FTP with TLS bolted on. Encrypts the control and data channels but keeps the two-connection architecture, so it inherits every firewall and NAT problem FTP has. Use it only when something requires it.
- SCP (port 22) — also over SSH, simpler and older. Fine for one-off file copies, no directory browsing or resume.
The naming is genuinely confusing and it matters: SFTP and FTPS are unrelated protocols that sound like variants of each other. SFTP is the one you want. If a host offers SFTP, use it and never think about passive mode again.
The practical case for SFTP over FTPS: one port, one connection, encrypted by default, and it uses SSH key authentication, which removes the password from the equation entirely.
Debugging an FTP connection
When FTP misbehaves, the two-connection design means you need to know which connection failed. Verbose output tells you:
curl -v --ftp-pasv ftp://example.com/ --user name:password
Read it in order:
- A 220 greeting means the control connection on port 21 is open. If you never see this, port 21 is blocked or the service is not running.
- A 230 means the login succeeded. A 530 means credentials were rejected — a control-channel problem, nothing to do with data ports.
- A 227 in response to PASV includes the address and port for the data connection. Look at the address it gives you. If it is a private address like 192.168.x.x or 10.x.x.x and you are connecting from outside, the server is misconfigured behind NAT and that is your bug.
- A hang after 227 means the data connection could not be established. Either the advertised port range is closed on the server’s firewall, or the address it advertised is unreachable.
That 227 response is where most FTP mysteries resolve. It is the one place the protocol tells you exactly what it expects to happen next, and comparing that against what can actually happen usually ends the investigation.
Why deploys stopped using it
FTP as a deployment mechanism has a deeper problem than the protocol: it deploys by copying files over the top of running files. There is no atomicity. Halfway through an upload, your site is half the old version and half the new one, and a request arriving in that window gets whichever mix exists at that instant.
It also leaves no record. There is no commit, no build log, and no answer to what changed. Reverting means remembering what the previous files were, which means having them, which people usually do not.
The alternative that replaced it is building from a repository. The repository is the record, the build produces an artifact, and the artifact is swapped in as a unit. Reverting is redeploying a previous build rather than reconstructing a directory from memory.
That is the real argument against FTP in 2026 — not that it is insecure, though it is, but that copying files onto a live server is a deployment model with no undo.
How this fits the rest of the stack
The reason FTP persisted so long is that it made the file system on the server feel directly editable, which is genuinely convenient right up to the moment you need to know what changed. Deploying from a git repository keeps that record: the build log shows what was built, from which commit, and rolling back is selecting a previous deploy rather than re-uploading files. Deploying from GitHub on RunxBuild covers that path, and managed WordPress includes a dashboard file manager for the times you genuinely do need to touch a file directly. If you are pricing the service, storage, and bandwidth together, the RunxBuild hosting calculator breaks them into line items.
Useful related references:
- What Port is SSH: 22 (Default), How to Change, and Why
- Default Port for SSH: Why 22, and When to Change It
- What Port for SSH: 22, 2222, and the Right Defaults
- Services on RunxBuild
FAQ
What is the difference between port 20 and port 21?
Port 21 is the control channel, carrying commands and responses for the whole session. Port 20 is the server’s source port for data transfers in active mode only. Since passive mode is now standard, port 20 is rarely used at all.
Why does FTP connect but hang on directory listings?
The control connection on port 21 is working and the data connection is not. Usually the server is behind NAT and advertising a private address in its PASV response, or its passive port range is blocked by a firewall.
Is SFTP the same as FTPS?
No, and the names are misleading. SFTP is a subsystem of SSH on port 22, using one encrypted connection. FTPS is FTP with TLS added, keeping the two-connection design and its firewall problems. SFTP is the better default.
Is FTP encrypted?
Plain FTP is not. Usernames, passwords, and file contents all travel in clear text and can be read by anything on the network path. There is no setting to enable encryption — you have to switch to SFTP or FTPS.
Should I use active or passive FTP mode?
Passive, essentially always. Active mode requires the server to open an inbound connection to the client, which client firewalls and NAT routers block by default. Every modern FTP client defaults to passive for this reason.