Loading learning content...
Every FTP session is a conversation between client and server, conducted in a language of simple text commands and numeric responses. This command language, defined in RFC 959 and extended by subsequent RFCs, provides a complete vocabulary for authentication, file management, data transfer, and session control.
Understanding FTP commands goes beyond rote memorization. Each command represents a design decision about what operations are essential for file transfer. Studying these commands reveals how protocol designers thought about user workflows, security boundaries, and system interoperability.
This page serves as both a learning resource and a reference. We'll explore commands grouped by function, with complete syntax, expected responses, and practical usage examples.
By the end of this page, you will understand the complete FTP command vocabulary: authentication commands for session establishment, file transfer commands for moving data, directory commands for navigation and organization, configuration commands for transfer settings, and control commands for session management. You'll know the syntax, parameters, and expected responses for each command.
Before diving into specific commands, let's establish the universal rules that govern all FTP command interactions.
Command Format
COMMAND<SP>argument<CRLF>
Response Format
XYZ<SP>text message<CRLF>
| Category | Purpose | Example Commands |
|---|---|---|
| Access Control | Session authentication and account management | USER, PASS, ACCT, REIN, QUIT |
| Transfer Parameter | Configure how data is transferred | PORT, PASV, TYPE, STRU, MODE |
| Service (File) | File operations—retrieve, store, delete | RETR, STOR, STOU, APPE, DELE, RNFR, RNTO |
| Service (Directory) | Directory navigation and management | CWD, CDUP, MKD, RMD, PWD, LIST, NLST |
| Miscellaneous | Session control and information | SYST, STAT, HELP, NOOP, ABOR, FEAT, OPTS |
FTP is a sequential protocol—send one command, wait for response, then send the next. Some command pairs are logically linked (RNFR must be followed by RNTO; USER is typically followed by PASS). Transfer commands (RETR, STOR, LIST) require prior PORT or PASV to establish the data channel.
Before any file operations, clients must authenticate. FTP's authentication model is straightforward (some would say too simple for modern security requirements), but understanding it is essential.
| Command | Syntax | Purpose | Typical Response |
|---|---|---|---|
| USER | USER username | Identify the user requesting access | 331 (need password) or 230 (logged in, no password needed) |
| PASS | PASS password | Provide password for USER | 230 (success), 530 (login failed) |
| ACCT | ACCT account-info | Provide additional account information | 230 (success), 202 (not needed) |
| REIN | REIN | Reinitialize—flush session, require new login | 220 (ready for new user) |
| QUIT | QUIT | Terminate session and close control connection | 221 (goodbye) |
USER Command
USER username\r
Identifies the user account for authentication. The server typically responds:
Security Note: Most servers respond 331 regardless of whether the username exists, preventing username enumeration attacks.
PASS Command
PASS password\r
Provides the password for the user specified in USER. The password is sent in cleartext—one of FTP's major security weaknesses.
Responses:
Anonymous FTP Convention: For anonymous access, use anonymous as username and conventionally an email address as password (purely informational, not validated).
12345678910111213141516171819202122232425262728
=== Standard Authentication ===<-- 220 FTP Server ready.--> USER alice<-- 331 Password required for alice.--> PASS secretpassword<-- 230 User alice logged in, proceed. === Anonymous Authentication ===<-- 220 FTP Server ready. Anonymous access permitted.--> USER anonymous<-- 331 Guest login ok, send your email address as password.--> PASS user@example.com<-- 230 Anonymous access granted, restrictions apply. === Authentication Failure ===<-- 220 FTP Server ready.--> USER alice<-- 331 Password required for alice.--> PASS wrongpassword<-- 530 Login incorrect. === Session Reinitialize ===[Already logged in as alice]--> REIN<-- 220 Service ready for new user.--> USER bob<-- 331 Password required for bob....FTP transmits USER and PASS in cleartext over the network. Anyone monitoring the network can capture credentials. For any non-anonymous access, use FTPS (FTP over TLS) or SFTP (SSH File Transfer Protocol) instead of plain FTP.
Before transferring data, clients configure how that data will be transmitted. These commands set up the data connection and specify data representation.
| Command | Syntax | Purpose | Typical Response |
|---|---|---|---|
| PORT | PORT h1,h2,h3,h4,p1,p2 | Specify client's data port (Active Mode) | 200 (OK), 500 (syntax error) |
| PASV | PASV | Request server to enter Passive Mode | 227 (Entering Passive Mode) |
| EPRT | EPRT |prot|addr|port| | Extended PORT for IPv6 | 200 (OK), 522 (not supported) |
| EPSV | EPSV | Extended PASV for IPv6 | 229 (Entering Extended Passive Mode) |
| TYPE | TYPE type-code | Set representation type (A=ASCII, I=Binary) | 200 (OK) |
| STRU | STRU struct-code | Set file structure (F=File, R=Record) | 200 (OK) |
| MODE | MODE mode-code | Set transfer mode (S=Stream, B=Block) | 200 (OK) |
TYPE Command — Representation Type
TYPE type-code [format-control]\r
Sets how data is represented during transfer:
| Code | Type | Description |
|---|---|---|
| A | ASCII | Text mode; line endings translated |
| I | Image (Binary) | Exact byte-for-byte copy |
| E | EBCDIC | IBM mainframe text encoding |
| L | Local | Custom byte size (followed by size) |
ASCII mode has optional format control (N=Non-print, T=Telnet, C=Carriage Control), but these are rarely used.
Practical Usage:
--> TYPE A
<-- 200 Type set to A.
--> TYPE I
<-- 200 Type set to I.
Critical: Set TYPE before every transfer to ensure correct handling. Transferring binary files in ASCII mode corrupts them; transferring text files in binary mode may leave line endings unconverted.
STRU Command — File Structure
STRU structure-code\r
| Code | Structure | Description |
|---|---|---|
| F | File | No internal structure—continuous byte stream (default) |
| R | Record | File as sequence of sequential records |
| P | Page | File as sequence of independent indexed pages |
Modern usage almost exclusively uses STRU F (the default). Record and page structures were for mainframe systems with structured file concepts that don't map to modern file systems.
MODE Command — Transfer Mode
MODE mode-code\r
| Code | Mode | Description |
|---|---|---|
| S | Stream | Continuous byte stream; EOF by connection close (default) |
| B | Block | Data in headers+blocks; supports restart markers |
| C | Compressed | Run-length compression (rarely implemented) |
Stream mode is the universal default. Block mode provides restart capability but adds complexity. Compressed mode is obsolete—modern files are already compressed, and network-level compression is more efficient.
Upon login, most servers default to: TYPE A (ASCII), STRU F (File), MODE S (Stream). For reliable binary transfers, always explicitly set TYPE I before retrieving or storing non-text files.
The core purpose of FTP: transferring files between client and server. These commands handle downloading, uploading, appending, and managing file content.
| Command | Syntax | Purpose | Data Direction |
|---|---|---|---|
| RETR | RETR filename | Retrieve (download) a file | Server → Client |
| STOR | STOR filename | Store (upload) a file | Client → Server |
| STOU | STOU | Store unique—server generates filename | Client → Server |
| APPE | APPE filename | Append to existing file (or create if not exists) | Client → Server |
| DELE | DELE filename | Delete a file | N/A (no data connection) |
| RNFR | RNFR oldname | Rename From—specify file to rename | N/A |
| RNTO | RNTO newname | Rename To—complete rename operation | N/A |
| REST | REST offset | Restart—set byte offset for resumed transfer | N/A |
| ABOR | ABOR | Abort current transfer | N/A |
RETR — Retrieve (Download)
RETR pathname\r
Transfers a file from server to client. Requires prior PORT/PASV for data connection.
Sequence:
--> PASV
<-- 227 Entering Passive Mode (192,168,1,100,195,80)
[Client connects to 192.168.1.100:50000]
--> RETR /path/to/file.zip
<-- 150 Opening BINARY mode data connection for file.zip (1048576 bytes).
[File data flows on data connection]
[Data connection closed by server]
<-- 226 Transfer complete.
Response codes:
STOR — Store (Upload)
STOR pathname\r
Transfers a file from client to server. Overwrites if file exists.
Sequence:
--> PASV
<-- 227 Entering Passive Mode (192,168,1,100,195,88)
[Client connects to data port]
--> STOR /uploads/newfile.dat
<-- 150 Opening BINARY mode data connection for newfile.dat.
[Client sends file data]
[Client closes data connection to signal EOF]
<-- 226 Transfer complete.
STOU — Store Unique
STOU\r
Like STOR, but server generates a unique filename. The server includes the created filename in its response—useful for avoiding overwrites.
APPE — Append
APPE pathname\r
Appends data to an existing file. If file doesn't exist, it's created. Useful for log aggregation or incremental uploads.
REST — Restart (Resume)
REST byte-offset\r
Sets the restart point for the next RETR or STOR command. Enables resumption of interrupted transfers.
Resumed Download Sequence:
[Previous download interrupted at 524288 bytes]
--> REST 524288
<-- 350 Restarting at 524288. Send STORE or RETRIEVE.
--> RETR largefile.iso
<-- 150 Opening BINARY mode data connection.
[Server sends bytes starting at offset 524288]
<-- 226 Transfer complete.
Important: REST only works reliably with TYPE I (binary). ASCII mode transfers may have different byte counts due to line ending transformation.
1234567891011121314151617181920212223
=== Rename a File ===--> RNFR oldname.txt<-- 350 File exists, ready for destination name.--> RNTO newname.txt<-- 250 RNTO command successful. === Rename Failure (RNFR must precede RNTO) ===--> RNTO newname.txt<-- 503 Bad sequence of commands. RNFR required first. === Delete a File ===--> DELE unwanted.txt<-- 250 DELE command successful. === Delete Failure ===--> DELE nonexistent.txt<-- 550 nonexistent.txt: No such file or directory. === Abort a Transfer ===[Large file transfer in progress]--> ABOR<-- 426 Transfer aborted. Data connection closed.<-- 226 Abort successful.Renaming requires two commands: RNFR (Rename From) specifies the source, then RNTO (Rename To) specifies the destination. RNTO must immediately follow RNFR. This separation allows atomic cross-directory moves on some servers.
FTP provides a complete set of commands for navigating and managing directory structures on the remote server.
| Command | Syntax | Purpose | Typical Response |
|---|---|---|---|
| CWD | CWD pathname | Change Working Directory | 250 (success), 550 (failed) |
| CDUP | CDUP | Change to Parent Directory (CWD ..) | 200 or 250 (success) |
| PWD | PWD | Print Working Directory—show current location | 257 "pathname" is current directory |
| MKD | MKD pathname | Make Directory—create new directory | 257 "pathname" created |
| RMD | RMD pathname | Remove Directory—delete empty directory | 250 (success) |
| LIST | LIST [pathname] | List directory contents (detailed) | 150/226 (data on data connection) |
| NLST | NLST [pathname] | Name List—filenames only (simple) | 150/226 (data on data connection) |
| MLSD | MLSD [pathname] | Machine-parseable directory listing | 150/226 (RFC 3659) |
| MLST | MLST [pathname] | Machine-parseable single file info | 250 (info in response) |
PWD — Print Working Directory
--> PWD
<-- 257 "/home/alice/documents" is the current directory.
The quoted pathname in the response is the canonical current directory. The quotes allow paths with spaces to be unambiguous.
CWD — Change Working Directory
--> CWD /var/www/html
<-- 250 Directory successfully changed.
--> CWD nonexistent
<-- 550 Failed to change directory.
Absolute paths start with /. Relative paths navigate from current directory.
MKD — Make Directory
--> MKD newdir
<-- 257 "/home/alice/newdir" directory created.
--> MKD existing
<-- 550 existing: File exists.
The 257 response includes the full path of the created directory.
LIST vs NLST vs MLSD
Three commands retrieve directory contents, with different formats:
LIST — Detailed listing (human-readable)
--> LIST
<-- 150 Here comes the directory listing.
[Data connection receives:]
drwxr-xr-x 2 alice users 4096 Jan 15 10:30 subdir
-rw-r--r-- 1 alice users 12345 Jan 14 09:15 file.txt
[Data connection closes]
<-- 226 Directory send OK.
LIST format varies by server (Unix-style ls output is common but not standardized).
NLST — Name list (simple)
--> NLST
<-- 150 Here comes the directory listing.
[Data connection receives:]
subdir
file.txt
[Data connection closes]
<-- 226 Directory send OK.
NLST returns filenames only—easier to parse but less information.
MLSD — Machine-parseable listing (RFC 3659)
--> MLSD
<-- 150 Here comes the directory listing.
[Data connection receives:]
type=dir;modify=20240115103000;perm=el; subdir
type=file;size=12345;modify=20240114091500;perm=r; file.txt
[Data connection closes]
<-- 226 Directory send OK.
MLSD provides structured, machine-parseable output with standardized fields. Modern clients should prefer MLSD when available.
For programmatic FTP clients, always prefer MLSD over LIST. LIST format varies wildly between servers (Windows vs Unix vs mainframe), making reliable parsing difficult. MLSD provides consistent, standardized fields (type, size, modify, perm, etc.) that are reliably parseable.
Beyond file and directory operations, FTP provides commands for system information, capability discovery, and session control.
| Command | Syntax | Purpose | Notes |
|---|---|---|---|
| SYST | SYST | Query server system type | Identifies OS/platform |
| STAT | STAT [path] | Query server/transfer status | Without arg: connection status; with arg: file info |
| HELP | HELP [command] | Request help information | Lists commands or specific command info |
| NOOP | NOOP | No operation—keep connection alive | Resets idle timeout |
| FEAT | FEAT | List server features/extensions | RFC 2389—capability discovery |
| OPTS | OPTS feature options | Configure a feature | Common: OPTS UTF8 ON |
| SITE | SITE command | Server-specific commands | Non-standard, server-dependent |
| SIZE | SIZE filename | Get file size in bytes | RFC 3659 extension |
| MDTM | MDTM filename | Get file modification time | RFC 3659 extension |
SYST — System Identification
--> SYST
<-- 215 UNIX Type: L8
Identifies the server's operating system and file system characteristics. Common responses:
UNIX Type: L8 — Unix-like system with 8-bit bytesWindows_NT — Windows systemVMS — OpenVMS systemClients use SYST to adjust behavior (e.g., line ending expectations).
FEAT — Feature Discovery
--> FEAT
<-- 211-Features:
UTF8
MLST Type*;Size*;Modify*;Perm*;
PASV
EPSV
EPRT
REST STREAM
SIZE
MDTM
<-- 211 End
FEAT lists server-supported extensions beyond RFC 959. Critical for clients to know what capabilities are available (EPSV, MLSD, UTF8, etc.).
SIZE and MDTM — File Metadata
--> SIZE largefile.iso
<-- 213 4700000000
--> MDTM document.pdf
<-- 213 20240115093045
SIZE returns file size in bytes. MDTM returns modification time in YYYYMMDDHHMMSS format (UTC). Both are essential for sync tools that need to compare files without downloading.
NOOP — Keep-Alive
--> NOOP
<-- 200 NOOP ok.
Does nothing except reset the server's idle timeout. Clients performing long local operations should periodically send NOOP to prevent session timeout.
SITE — Server-Specific Commands
--> SITE CHMOD 755 script.sh
<-- 200 SITE CHMOD command successful.
SITE provides a mechanism for server-specific functionality without standardization. Common SITE commands:
SITE CHMOD mode file — Change permissions (Unix servers)SITE UMASK mask — Set default permissionsSITE HELP — List available SITE commandsBefore using extended commands (MLSD, EPSV, UTF8, SIZE, MDTM), check FEAT to confirm support. Attempting unsupported commands results in 500 or 502 errors and may confuse some older servers.
Real FTP operations require specific command sequences. Here are the complete sequences for common tasks:
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849
=== Download a Binary File === # 1. Connect and authenticate[TCP Connect to server:21]<-- 220 FTP Server Ready.--> USER alice<-- 331 Password required.--> PASS ********<-- 230 Login successful. # 2. Check capabilities--> FEAT<-- 211-Features: PASV SIZE MDTM<-- 211 End # 3. Navigate to directory--> CWD /data/downloads<-- 250 Directory changed.--> PWD<-- 257 "/data/downloads" is current directory. # 4. Get file information--> SIZE largefile.zip<-- 213 1073741824--> MDTM largefile.zip<-- 213 20240115120000 # 5. Set binary mode--> TYPE I<-- 200 Type set to I. # 6. Initiate transfer (passive mode)--> PASV<-- 227 Entering Passive Mode (192,168,1,100,195,80)[Connect to 192.168.1.100:50000] # 7. Request file--> RETR largefile.zip<-- 150 Opening BINARY mode data connection (1073741824 bytes).[Receive file content on data connection][Data connection closes]<-- 226 Transfer complete. # 8. Verify and cleanup--> QUIT<-- 221 Goodbye.1234567891011121314151617181920212223242526272829303132333435
=== Upload a File with Directory Creation === # 1. Authenticate (abbreviated)--> USER alice<-- 331 Password required.--> PASS ********<-- 230 Login successful. # 2. Navigate/create destination--> CWD /uploads<-- 250 Directory changed.--> MKD 2024-01<-- 257 "/uploads/2024-01" created.--> CWD 2024-01<-- 250 Directory changed. # 3. Set binary mode--> TYPE I<-- 200 Type set to I. # 4. Initiate upload--> PASV<-- 227 Entering Passive Mode (192,168,1,100,195,88)[Connect to data port] # 5. Store file--> STOR report.pdf<-- 150 Opening BINARY mode data connection.[Send file content][Close data connection to signal EOF]<-- 226 Transfer complete. # 6. Verify upload--> SIZE report.pdf<-- 213 2048576123456789101112131415161718192021222324252627282930313233343536
=== Resume Interrupted Transfer === # Assume previous download stopped at byte 524288000 (500 MB) # 1. Authenticate--> USER alice<-- 331 Password required.--> PASS ********<-- 230 Login successful. # 2. Check server supports REST--> FEAT<-- 211-Features: REST STREAM ...<-- 211 End # 3. Navigate and set mode--> CWD /downloads<-- 250 Directory changed.--> TYPE I<-- 200 Type set to I. # 4. Set restart point--> REST 524288000<-- 350 Restarting at 524288000. Send STORE or RETRIEVE. # 5. Resume download--> PASV<-- 227 Entering Passive Mode (192,168,1,100,195,90)[Connect to data port]--> RETR bigfile.iso<-- 150 Opening BINARY mode connection for bigfile.iso[Server sends data starting at byte 524288000][Append received data to local partial file]<-- 226 Transfer complete.Even if you think the server defaults to the correct type, explicitly set TYPE I for binary files and TYPE A for text files. This prevents corruption from unexpected default settings or previous session state.
We've covered the complete FTP command vocabulary. Let's consolidate with a quick reference and key takeaways:
| Task | Commands | Notes |
|---|---|---|
| Login | USER, PASS | Always required (even anonymous) |
| Logout | QUIT | Cleanly terminates session |
| Navigate | CWD, CDUP, PWD | cd, cd .., pwd equivalents |
| List files | LIST, NLST, MLSD | MLSD preferred for parsing |
| Download | TYPE I, PASV, RETR | Set binary; establish data conn; retrieve |
| Upload | TYPE I, PASV, STOR | Set binary; establish data conn; store |
| Resume | REST offset, RETR/STOR | Set offset before transfer command |
| Delete | DELE | Removes file |
| Rename | RNFR, RNTO | Must be sequential pair |
| Create dir | MKD | Make directory |
| Remove dir | RMD | Directory must be empty |
| File info | SIZE, MDTM | Size and modification time |
| Keep alive | NOOP | Prevents timeout |
Module Complete:
You've now completed a comprehensive study of FTP Overview. You understand:
This knowledge provides a solid foundation for working with FTP in any context—whether debugging connection issues, implementing FTP clients, configuring servers, or simply understanding how file transfer works at a fundamental level.
Congratulations! You've mastered FTP fundamentals. You can now confidently work with FTP connections, troubleshoot issues by analyzing command sequences, implement FTP clients using proper command protocols, and understand why FTP behaves as it does. The next modules will explore FTP in practice: operations, secure alternatives (SFTP/SCP), and remote access protocols.