📑 Daftar Isi
- Step 1: Confirm the Symptom — Refused or Timeout?
- Step 2: Check the Pure-FTPd Service
- Step 3: Check the Listener and IP Binding
- Step 4: Rebuild the Configuration from WHM
- Step 5: Check the Firewall — CSF, cPanel Firewall, and Cloud
- Step 6 (Bonus): Blocked Passive Ports
- Quick Troubleshooting Table
- FAQ
How to Fix cPanel FTP Connection Refused on Production Servers: 5 Quick Steps for NOC Engineers 2026
Alright, let’s skip the fluff. Client calls at 9 AM, the website loads fine, SSH works, but FTP keeps throwing connection refused since yesterday afternoon. You can hear in their voice they’ve been testing it on their own for hours. Deep breath — cases like this are rarely as scary as they look.
This isn’t a textbook walkthrough. It’s a field checklist from tickets I’ve handled way too many times, ordered from the fastest check to the deepest one. Follow it in order, don’t skip around, and you’ll save yourself an hour of guesswork.
Before you touch anything, there’s one concept you need to nail down: connection refused is not the same as a connection timeout. Refused means the server answered with a TCP reset — something actively said “no”. Timeout means your packets are being dropped silently. That one detail decides exactly where you look next. If it’s refused, there are really only two suspects: the FTP service is dead, or port 21 is blocked by something that answers with a reset.
The production impact is real. Your client can’t upload files, content updates grind to a halt, deployment workflows stall, and if it’s shared hosting, support tickets pile up because other users panic too. The three most common causes I keep seeing in the field: first, pure-ftpd crashed or got OOM-killed and never came back up. Second, a firewall like CSF or a cloud firewall blocking port 21 because of a misconfiguration. Third, the client’s IP landed in a deny list because of a brute-force detection mistake.
Okay, let’s execute. Every step below runs from SSH as root. If you don’t have SSH access yet, ask your hosting provider first — proper diagnosis happens on the server, not just in the cPanel interface.
Step 1: Confirm the Symptom — Refused or Timeout?
Don’t restart anything yet. Test from the client side first so you know where to look. Check port 21 with netcat or telnet:
nc -zvw5 ftp.domain.com 21
telnet ftp.domain.com 21
A healthy response looks roughly like this:
220---------- Welcome to Pure-FTPd ----------
220-You are user number 1 of 500 allowed
220-Local time is now ...
220-Only anonymous FTP is banned
If you get “Connection refused”, something answered with a reset — the service is down or a firewall is actively dropping. If it hangs, times out, or says “Unable to connect”, your packets aren’t being answered at all, and a cloud-level firewall is the most likely culprit. Write down what you saw and move to Step 2.
One tip I learned the hard way: don’t only test from the server itself. Test from the outside too — an online port checker or a different VPS works great. I’ve seen servers look perfectly healthy from inside while the port is completely dead from the outside.
Step 2: Check the Pure-FTPd Service
cPanel’s default FTP server is Pure-FTPd, not vsftpd or proftpd. Check its status first:
systemctl status pure-ftpd
service pure-ftpd status
ps aux | grep pure-ftpd
If the output says “Active: inactive (dead)” or the process is missing, you found your culprit. Start it and make sure it auto-starts on boot:
systemctl start pure-ftpd
systemctl enable pure-ftpd
Then test from the client again. Still refused? Then the service is probably failing to start. Check the logs:
journalctl -u pure-ftpd -n 50
grep -i pure-ftpd /var/log/messages
The most common errors in the log: port 21 is already held by another service (like a leftover proftpd or vsftpd that was installed ages ago), or pure-ftpd can’t read its pid file. Before you restart anything, check who owns port 21:
ss -tlnp | grep :21
If another process is holding it, kill it first. I’ve debugged more “connection refused” cases than I care to count where the real cause was a stale FTP service still grabbing the port and pure-ftpd failing silently. Stop the old one, then start pure-ftpd.
Step 3: Check the Listener and IP Binding
Once the service is running, make sure it’s actually listening on the public IP — not just on localhost:
netstat -tlnp | grep :21
ss -tlnp | grep :21
A healthy line looks like this:
tcp 0 0 0.0.0.0:21 0.0.0.0:* LISTEN 1234/pure-ftpd
If the only thing you see is 127.0.0.1:21, pure-ftpd is only listening on localhost. No client will ever reach it from outside, and that’s almost always a broken configuration. And if there’s no line at all, the service is down — go back to Step 2.
While you’re at it, verify the client is connecting to the right IP. DNS sometimes points to an old IP or a different server. Check it:
dig +short ftp.domain.com
Compare it with the server’s current public IP. If they don’t match, that’s a DNS problem, not an FTP problem.
Step 4: Rebuild the Configuration from WHM
If the service is up, the listener is fine, but you still get refused, the configuration is the usual suspect. The cleanest fix: rebuild from WHM.
Log into WHM (usually port 2087), go to Home > Services Configuration > FTP Server Configuration, and hit the Build and Install button. This regenerates a clean pure-ftpd config file and re-installs the binary if something got corrupted.
After that, inspect the config manually:
cat /etc/pure-ftpd.conf
The settings that cause the most trouble, and that you should always check:
ForcePassiveIP— if the server moved to a new IP and this still points to the old one, external FTP connections die completely. Update it to the current public IP.PassivePortRange— if it’s empty, the default range is used. Either way, make sure that range is also open in the firewall.MaxClientsNumber— if it’s set to 0, nobody can connect at all.AnonymousOnly— don’t enable this if clients need to log in with a cPanel account.MaxIdleTime— a very low value makes connections drop mid-transfer.
After the rebuild, restart the service:
systemctl restart pure-ftpd
Run the Step 1 test again. If you’re getting the 220 banner, the FTP layer is healthy.
Step 5: Check the Firewall — CSF, cPanel Firewall, and Cloud
This is the number one source of problems in production. If the service and listener are healthy but the client still gets refused, the firewall is the suspect. Start local, then go cloud.
If the server runs CSF, check its status and its port list:
csf -l
grep -E '^TCP_IN' /etc/csf/csf.conf
Make sure port 21 is in the TCP_IN list. If it’s missing, port 21 is blocked for everyone. Then check if the client’s IP is blocked:
csf -g 103.90.xxx.xxx
If the output shows “csf: DROP”, the IP is in the deny list. Remove it:
csf -dr 103.90.xxx.xxx
Or, if you want to be safer, use the temporary remove: csf -tr 103.90.xxx.xxx. The difference: if that IP is genuinely an attacker, LFD will re-block it automatically.
csf -f (flush) on a production server without a very good reason. It drops every active connection, including your own SSH session. If an IP was blocked by mistake, just use csf -dr.Then figure out why the IP got blocked. The logs are here:
tail -100 /var/log/csf.log
tail -100 /var/log/lfd.log
Usually there was an FTP brute-force attempt from that IP earlier and LFD blocked it. But be careful: dynamic IPs can trigger false positives, especially behind CGNAT. If the IP is legit, remove it and ask the client to change their FTP password.
Don’t forget the other two firewall layers:
- cPanel’s built-in firewall: WHM > Security Center > Firewall > IP Deny Manager. Check whether the client’s IP is listed there.
- Cloud firewall: AWS security groups, DigitalOcean/Vultr/Linode firewalls, etc. This is what usually causes timeouts when port 21 isn’t open.
Finally, check account-level restrictions: WHM > Tweak Settings has FTP options, and under cPanel > FTP Accounts make sure the user is still active and not IP-restricted. Sometimes the problem isn’t the network at all — it’s the account settings.
Step 6 (Bonus): Blocked Passive Ports
This is the sneakiest case. The client can log in, but listing a directory or uploading throws connection refused or just hangs. That’s not port 21 — that’s the data connection on passive ports.
Pure-FTPd uses a passive port range, defaulting to 30000-50000 on cPanel. That range must be open in the firewall if the client uses passive mode — which is the default on almost every FTP client out there. In CSF, make sure the range is in TCP_IN:
TCP_IN = "20,21,30000:50000,25,22,53,80,443,..."
Then cross-check with the range in pure-ftpd.conf:
grep -i passive /etc/pure-ftpd.conf
After any change, restart both:
systemctl restart csf
systemctl restart pure-ftpd
If the client is in a hurry, tell them to use Active mode or SFTP as a stopgap while you fix the port range properly.
Quick Troubleshooting Table
| Symptom | Likely Cause | Fastest Fix |
|---|---|---|
| Connection refused on port 21 | pure-ftpd down or port held by another service | systemctl start pure-ftpd, check ss -tlnp | grep :21 |
| Refused but SSH works fine | CSF or cPanel firewall blocking port 21 | csf -g <IP>, check TCP_IN in csf.conf |
| Login OK but directory listing hangs | Passive range 30000-50000 blocked | Open the range in the firewall |
| Slow connection or timeout | Cloud firewall (AWS SG, DO, Vultr) blocking | Open port 21 in the security group |
| Refused after a server migration | ForcePassiveIP still pointing to the old IP | Update /etc/pure-ftpd.conf |
| Nobody can connect at all | MaxClientsNumber set to 0 or service down | Check config, restart pure-ftpd |

FAQ
Q: Why is FTP refused but SSH works fine?
Usually because port 21 is blocked by a firewall or the pure-ftpd service is down, while port 22 (SSH) is untouched. They’re separate services on separate ports, so it’s completely normal for only one to be affected.
Q: What’s the difference between FTP, FTPS, and SFTP?
FTP is port 21 and plaintext. FTPS is FTP over TLS, typically port 21 or 990, but the data connection still needs the passive range open. SFTP is SSH File Transfer running over port 22 — the simplest option if you just want the job done quickly.
Q: How do I open the passive ports in CSF?
Edit /etc/csf/csf.conf, make sure 30000:50000 is in the TCP_IN line, then restart csf. That range also needs to match PassivePortRange in /etc/pure-ftpd.conf.
Q: Pure-FTPd won’t start, what now?
Check journalctl -u pure-ftpd -n 50 first. The most common errors are port 21 being held by another service or a broken pid file. Stop the other service, or rebuild the config via WHM > FTP Server Configuration.
Q: Does cPanel use vsftpd?
No. cPanel’s default FTP server is Pure-FTPd. vsftpd is sometimes installed manually, but it can cause a port 21 conflict if both are running.
That’s it. Before you close the ticket, make sure you’ve checked: 1) refused vs timeout, 2) pure-ftpd status and the port 21 listener, 3) CSF plus cloud firewalls, 4) the passive port range. If everything checks out and the client can connect again, case closed. Done. For a deeper dive, read our basic CSF firewall guide, then check FTP vs SFTP vs FTPS so you pick the right protocol next time. If you want to get better at reaching your servers, our how to access SSH guide helps. The important part now: run the steps in order and write down the result of each one. Go!