Active and passive FTP
NAT, firewalls, and failed transfers
Diagnose an FTP session that logs in successfully but cannot list or transfer files.
Login works? Then your control connection works. If ls, get, or put hangs, look at the data connection. I see this weekly on partner setups where someone opened port 21 and stopped there.
The control channel and the data channel are separate TCP connections. Success on one does not imply success on the other. That is the first thing I explain when someone says “FTP auth is fine but transfers are broken.”
Ask the partner for the passive port range their server uses. Match it on the firewall before you test again.
This pattern is everywhere:
230 User logged in
ftp> epsv
229 Entering Extended Passive Mode (|||50021|)
ftp> ls
Then nothing. No 150, no listing, silence. The client never reached the passive port, or the firewall blocked it.
Sometimes you get an honest error instead of a hang:
ftp> ls
425 Can't open data connection
That usually means the server advertised a port your client cannot reach. Wrong public IP in the passive reply is the usual suspect on cloud VMs.
Walk the steps in order:
1. DNS and TCP reach port 21
2. 220 greeting arrives
3. login reaches 230
4. PASV or EPSV returns an endpoint
5. data TCP connection opens
6. 150 starts the operation
7. bytes and EOF cross the data channel
8. 226 completes the command
If step 4 shows 10.0.0.8 to an Internet client, fix NAT on the server. If step 5 times out, open the passive port range on the firewall.
FTPS makes this harder because control commands are encrypted. Configure a fixed passive range and allow it explicitly instead of hoping an FTP helper opens ports on the fly.
When step 5 fails, tcpdump often shows SYN packets to the wrong IP. Fix that before you toggle random GUI checkboxes.
Reproduce one failure with verbose logs. Stop at the first missing step and fix only that layer.
Lesson completed