FTP commands: a beginner's reference

Every basic FTP command, what it does, and what a typical exchange looks like.

FTP — the File Transfer Protocol — was standardised in 1985 as RFC 959 and is still in active use forty years later. Behind every FTP client you've ever used — FileZilla, WinSCP in FTP mode, the ftp command on macOS or Linux, the ftp.exe tool on Windows — is a small set of plain-text commands the client sends to the server, each followed by a numeric response code. This tutorial walks through all of them at a beginner level.

You don't need to know them by heart to use FTP — the GUI clients translate every drag-and-drop into the right sequence for you — but knowing what's actually being said is the difference between "the upload failed" and "the upload failed because the server returned 553 Could not create file, which means a permissions or quota issue on the destination directory."

How an FTP session is structured

An FTP session uses two network connections, which is the single most important thing to understand about the protocol:

Every interaction follows a request/response pattern. You (or your client) send a command on the control connection; the server replies with a three-digit response code and a human-readable message. Codes that start with 1 mean "in progress", 2 means "success", 3 means "more input needed", 4 means "temporary failure", and 5 means "permanent failure".

Logging in

The first thing every FTP session does is authenticate. Two commands handle the whole exchange.

USER alice
331 Please specify the password.
PASS hunter2
230 Login successful.
CommandWhat it does
USERSubmits the account name. The server typically replies with 331 to ask for a password.
PASSSubmits the password. A successful login replies with 230; a bad password gets 530.
ACCTOptional — supplies an account name for systems that distinguish user from billing account. Almost never used in modern deployments.
REINRe-initialise — logs the current user out without closing the connection. Useful for connection reuse, rare in practice.
QUITCloses the control connection politely. The server responds with 221.
FTP sends passwords in cleartext. Anyone who can sniff the network between you and the server sees them. For anything that matters, use FTPS (FTP over TLS, RFC 4217) or SFTP, which is a different protocol entirely — see the SFTP tutorial.

Moving around the server

CommandWhat it does
PWDPrint working directory — the server replies with the current remote directory, e.g. 257 "/home/alice".
CWDChange working directory. CWD /uploads moves to /uploads.
CDUPChange to the parent directory — the equivalent of CWD ..

Listing what's there

CommandWhat it does
LISTLong-form directory listing in a human-friendly format (similar to ls -l). The listing is sent on a freshly opened data connection.
NLSTNames only — one filename per line, no sizes or timestamps. Useful for scripts.
MLSDMachine-parseable listing (RFC 3659). Each line is structured as fact=value;fact=value; filename. Scripts should prefer this over LIST when available.
MLSTSame machine-parseable format, but for a single file rather than a directory.
SIZEReturns the size of one file in bytes. SIZE report.csv213 12345.
MDTMModification time of a file in UTC: MDTM report.csv213 20260616153000.

Transferring files

This is the core of FTP. Each transfer uses a fresh data connection, which is set up immediately before the transfer (see "Active vs Passive" below).

CommandWhat it does
RETRRetrieve — downloads the named file from the server. RETR report.csv
STORStore — uploads to the named file on the server. STOR report.csv
APPEAppend — uploads, but adds to the file instead of overwriting it.
STOUStore unique — uploads, but the server picks a unique filename and tells you what it chose. Avoids overwriting existing files.
RESTRestart — tells the server to begin the next transfer at byte offset N. Combined with RETR or STOR for resumable transfers.

Managing files and directories

CommandWhat it does
DELEDelete a file. DELE old-report.csv
MKDMake a directory. MKD archive
RMDRemove a directory (must be empty on most servers).
RNFR + RNTORename, in two steps. Send RNFR old-name, get 350, then send RNTO new-name.

Transfer type and mode

FTP can interpret bytes as either text (and translate line endings between systems) or as a raw binary stream. Modern usage is almost always binary.

CommandWhat it does
TYPE IImage / binary mode — transfer bytes verbatim. The right choice for almost everything.
TYPE AASCII mode — the server translates line endings to match the destination platform. Useful only for plain-text files between heterogeneous systems.
STRU FFile structure (the default and only common choice today). The other STRU values are historical relics.
MODE SStream mode (the default). Other modes exist for block-oriented transfers but aren't supported in modern deployments.

Active vs Passive: setting up the data connection

Before each transfer, the client and server need to agree on where the data connection will be. There are two patterns.

Active mode uses PORT: the client opens a listening socket on its own end and tells the server which IP and port to connect to. The server initiates the data connection. This pattern breaks behind most home and corporate firewalls because the server has to make an inbound TCP connection to the client.

Passive mode uses PASV: the server opens a listening socket and tells the client the IP and port. The client initiates both connections (control and data). This pattern works through most NATs and is the default in every modern client.

CommandWhat it does
PORTActive mode — tells the server the client's IP and port to connect to.
PASVPassive mode — asks the server to open a port and report it.
EPRT / EPSVIPv6-aware equivalents from RFC 2428. EPSV is what current FTP clients prefer.

Server information and helpers

CommandWhat it does
SYSTAsks the server what system it identifies as. Modern servers usually answer 215 UNIX Type: L8 regardless of the real OS.
STATReturns server status — running transfers, connection info, etc.
FEATLists the optional extensions the server supports (MLST, SIZE, UTF8, etc.). See RFC 2389.
OPTSSets options for an extension. OPTS UTF8 ON is common.
HELPAsks the server for a list of supported commands.
NOOPNo-operation — sends 200 OK back. Often used as a keep-alive ping.
SITEVendor-specific commands. SITE CHMOD 644 file is the most common.

What to do next

If you want to feel the protocol directly, install a command-line FTP client like lftp (Linux), ncftp (Linux / macOS), or use the built-in ftp.exe on Windows. Most of them will let you turn on a verbose mode (set ftp:debug true in lftp, debug in ncftp) that prints every line of the underlying conversation as the client sends it. Watching one or two real sessions go by is the fastest way to make the table above stick.

When you're ready to move beyond FTP, read the SFTP tutorial next — SFTP runs over SSH and looks similar at the client level, but underneath it's a different protocol with very different security properties.