Setting up an FTP server on Windows Server 2008/2012 should be straightforward, but many admins hit this exact roadblock. The server responds perfectly to local connections:
C:\>ftp localhost
Connected to WebHead1
220 Microsoft FTP Service
Yet remote connections mysteriously time out:
~>ftp x.x.x.x
ftp: Can't connect to x.x.x.x': Operation timed out
ftp: Can't connect to x.x.x.x'
While you've enabled "FTP Server" in Windows Firewall, IIS FTP requires specific rules:
netsh advfirewall firewall add rule name="FTP Service" action=allow protocol=TCP dir=in localport=21
netsh advfirewall firewall add rule name="FTP Passive" action=allow protocol=TCP dir=in localport=49152-65535
For passive FTP (the default in IIS), you must also configure port ranges in IIS Manager:
- Open IIS Manager > FTP Firewall Support
- Set "Data Channel Port Range" to 49152-65535
- Enter your external IP in "External IP Address"
Three often-overlooked network issues:
# Verify basic connectivity first:
Test-NetConnection x.x.x.x -Port 21
If this fails, check:
- NAT configuration on routers (port forwarding 21 AND passive range)
- ISP blocking port 21 (common in residential networks)
- Corporate firewalls intercepting FTP traffic
Add these diagnostic commands to your toolkit:
# Check if FTP service is actually listening:
netstat -ano | findstr :21
# Verify IIS authentication settings:
Get-WebConfigurationProperty -pspath 'MACHINE/WEBROOT/APPHOST'
-filter "system.ftpServer/security/authentication/*"
-name "enabled" | Format-Table -AutoSize
Modern networks often break passive FTP. Implement this PowerShell fix:
# Set passive mode response to external IP
Add-WebConfigurationProperty -pspath 'MACHINE/WEBROOT/APPHOST'
-filter "system.ftpServer/firewallSupport"
-name "externalIp4Address" -value "YOUR_EXTERNAL_IP"
# Configure data channel ports
Set-WebConfigurationProperty -pspath 'MACHINE/WEBROOT/APPHOST'
-filter "system.ftpServer/firewallSupport"
-name "dataChannelPortRange" -value "50000-50100"
Use Wireshark with this capture filter:
tcp port 21 or tcp portrange 49152-65535
Look for:
- SYN packets reaching your server
- SYN-ACK responses from IIS
- ACK completion (or lack thereof)
This is one of those frustrating situations where your IIS FTP server appears perfectly configured - it accepts local connections via ftp localhost
or 127.0.0.1
, but times out completely when attempting remote access. Let's break this down systematically.
Even though you've checked "FTP Server" in Windows Firewall, there's more to it:
# Check specific FTP firewall rules with PowerShell
Get-NetFirewallRule -DisplayName "FTP*" | Select-Object DisplayName,Enabled,Profile,Direction,Action
# Example output should show both inbound rules enabled:
# DisplayName : FTP Server (FTP Traffic-In)
# Enabled : True
# Profile : Any
# Direction : Inbound
# Action : Allow
If these aren't enabled, create them manually:
New-NetFirewallRule -DisplayName "FTP Server (Port 21)" -Direction Inbound -Protocol TCP -LocalPort 21 -Action Allow
New-NetFirewallRule -DisplayName "FTP Passive (Port Range 50000-50100)" -Direction Inbound -Protocol TCP -LocalPort 50000-50100 -Action Allow
Before blaming IIS, verify basic connectivity:
# From remote machine test basic connectivity:
telnet x.x.x.x 21
# or with PowerShell:
Test-NetConnection x.x.x.x -Port 21
If these fail, the issue is network-related, not FTP-specific. Check:
- NAT configurations if behind a router
- ISP blocking port 21 (common in residential networks)
- Corporate firewall restrictions
The "All Unassigned" IP binding can sometimes cause issues. Try explicitly binding:
# In IIS Manager:
1. Select FTP Site -> Bindings
2. Add explicit binding for server's public IP
3. Restart FTP service
For advanced scenarios, check the IIS configuration file:
# Location:
%SystemDrive%\\inetpub\\temp\\appPools\\YourFTPSite\\config\\applicationHost.config
# Look for <site> node with your FTP configuration
# Verify bindings and physical path
Many remote connection failures stem from passive FTP misconfiguration. In IIS:
1. FTP Firewall Support settings must match your public IP
2. Define a passive port range (e.g., 50000-50100)
3. Ensure firewall allows this range
For complex NAT scenarios, you might need:
# In IIS 7.0+ applicationHost.config:
<ftpServer>
<firewallSupport>
<externalIpAddress>your.public.ip</externalIpAddress>
<dataChannelPortRange min="50000" max="50100" />
</firewallSupport>
</ftpServer>
Enable detailed logging (IIS Manager -> FTP Logging) and examine:
# Default log location:
%SystemDrive%\\inetpub\\logs\\LogFiles\\FTPSVC1\\
# Filter for failed attempts:
Select-String -Path "*.log" -Pattern "FAILED"
For real-time monitoring, use:
# PowerShell command to watch logs:
Get-Content -Path "C:\\inetpub\\logs\\LogFiles\\FTPSVC1\\*.log" -Wait
When traditional methods fail, try these advanced techniques:
# 1. Use PortQry to test FTP service response:
portqry.exe -n x.x.x.x -e 21 -p TCP
# 2. Check if IIS actually received the request:
netsh http show servicestate view=requestq
# 3. Verify the FTP service is listening:
netstat -ano | findstr ":21"
As a last resort, completely reset IIS and FTP components:
# Remove and reinstall FTP service:
dism /online /disable-feature /featurename:IIS-FTPServer
dism /online /enable-feature /featurename:IIS-FTPServer
# Reset IIS configuration:
%windir%\\system32\\inetsrv\\appcmd list site /xml > backup.xml
iisreset /stop
del /q /s %windir%\\system32\\inetsrv\\config\\applicationHost.config
iisreset /start
Remember to restore your configuration from backup.xml after verification.
- Verified physical network connectivity
- Confirmed port 21 isn't blocked by ISP
- Checked both Windows Firewall and any third-party firewalls
- Validated IIS bindings and FTP site permissions
- Reviewed detailed FTP logs for connection attempts
- Tested with multiple FTP clients (FileZilla, WinSCP, command-line)