NewYour coding agent can read the release notes before it upgrades.Set up the MCP server →
NuGet · #855 most downloaded on NuGet
An FTP and FTPS client for .NET & .NET Standard, optimized for speed. Provides extensive FTP commands, File uploads/downloads, SSL/TLS connections, Directory listing parsing, File hashing/checksums, File permissions/CHMOD, FTP proxies, FXP transfers, UTF-8 support, Async/await support, Powershell support and more. Written entirely in C#, with no external dependencies.
Last release 15 days ago
17 Sep 2026
Release timing varies
gaps range from 8 days to 6 months
Most releases are documented
notes for 49 of the last 60 stable releases
Nothing withdrawn
no release was ever pulled
10 years old
221 releases · first in 2016
New: CompareFile and CompareFileAsync methods to quickly perform various equality checks on a uploaded/downloaded file
CompareFile and CompareFileAsync methods to quickly perform various equality checks on a uploaded/downloaded fileFix: When download fails and we need to retry on failed verification, ensure that file is re-downloaded
FtpStatus.Failed is returned instead of FtpStatus.SkippedUpload and UploadAsync now returns FtpStatus to indicate skipped, success or failedOne column per quarter.
Fix: Proper session handling for FXP connections and disconnection of cloned connections
DownloadFile when appending is usedNew: AutoDetect and AutoConnect now auto-configure for Azure FTP servers using known connection settings
AutoDetect and AutoConnect now auto-configure for Azure FTP servers using known connection settings
FtpProfile to use LoadProfile rather than setting each property individuallyFtpProfile for Azure auto configurationFtpExceptionFtpProfile are now serializable in .NET FrameworkNew: TransferFile and TransferDirectory methods to transfer files from server to server (thanks n0ix)
New: Predefined rules for filtering on file name using regular expressions (thanks n0ix)
New: Support for MMD5 file hashing command to validate downloaded/uploaded files. (thanks n0ix)
Begin* and End* methods for .NET 4.5 and onwards as async/await is supported.GetHashAlgorithmAsync and SetHashAlgorithmAsync implemented as true async methods with cancellation supportGetObjectInfoAsync implemented as true async methods with cancellation supportNew: Download and upload file methods indicate if file was transferred, skipped or failed to transfer
DownloadFile and UploadFile return FtpStatus instead of boolean flag for tri-state feedbackNew: Support for XCRC FTP Command and CRC32 hash support to validate downloaded/uploaded files (thanks n0ix)
Fix: Calculation of local file path during DownloadFolder sometimes ignores base directory
New: Support multi-file progress tracking by indicating file index and local & remote path of the file
UploadDirectory and DownloadDirectory now supports tracking progress of the entire taskUploadFiles and DownloadFiles now supports tracking progress for both sync/async methodsIFtpClient interface by adding new UploadDirectory and DownloadDirectory methodsNew: UploadDirectory and UploadDirectoryAsync methods to recursively upload or mirror a directory
UploadDirectory and UploadDirectoryAsync methods to recursively upload or mirror a directory
DownloadDirectory and DownloadDirectoryAsync methods to recursively download or mirror a directorySubType property of FtpListItemGetListing when recursing into self directoryCreateDirectory and CreateDirectoryAsync now return a flag indicating if it was created or skippedFtpListItemCreateDirectory by skipping the directory exists checkFix: Detect "file size not allowed in ASCII" string for French FTP servers
Fix: TimeoutException when trying to read FTP server reply after Download/Upload
New: Add SendHost and SendHostDomain to control if HOST command is sent after handshake (thanks dansharpe83)
SendHost and SendHostDomain to control if HOST command is sent after handshake (thanks dansharpe83)Fix: Read stale NOOP responses after file transfer and also after 226 Transfer complete (thanks aliquid)
226 Transfer complete (thanks aliquid)
TimeConversion property to assume UTC timestampsNew: Keep control socket alive during long file transfers using NOOP (thanks aliquid)
NoopInterval property to control interval of NOOP commands (thanks aliquid)TimeConversion property to control if timestamps are converted from UTC into local timeFtpExists to FtpRemoteExists to make its usage clearFtpClient to support hostnames in Uri formatNew: ValidateCertificateRevocation property to control if certificate revocation is checked.
ValidateCertificateRevocation property to control if certificate revocation is checked.New: ValidateAnyCertificate property to validate any received server certificate, useful for Powershell
ValidateAnyCertificate property to validate any received server certificate, useful for Powershell
New: Override the server-specific recursive LIST detection by setting RecursiveList
RecursiveList
Fix: Verification of the MD5 Hash when file name contains spaces (thanks Nimelo)
Fix: Safely absorb TimeoutException thrown after the file has fully uploaded/downloaded
New: Progress reporting for synchronous methods Upload, Download, UploadFile and DownloadFile are now sent via delegates
Upload, Download, UploadFile and DownloadFile are now sent via delegates
IProgress for async methodsFix: Correctly assume Unix file listing parser for SunOS & Solaris servers
New: Support detection of Sun OS Solaris FTP OS and server (allows for server specific commands)
Fix: Unable to upload files to OpenVMS servers if path contains numeric characters
Connect & ConnectAsync throw ArgumentException when passing an incomplete FtpProfileNew: Auto-detect the correct FTP listing parser when SYST command fails (IIS, Azure, OpenVMS)
New: Improved transfer rate throttling when using an upload/download speed limit (thanks wakabayashik)
New: Support detection of XLight FTP server software (allows for server specific commands)
GetListing supports new FtpListOption.UseStat)GetFileSize always returns 0 instead of correct file size (thanks RadiatorTwo)Fix: FileExists and FileExistsAsync support switching to binary mode for servers that need it
FileExists and FileExistsAsync support switching to binary mode for servers that need itFix: Error using BlueCoat proxy to an FTP server on a port other than port 21
New: Change Capability API to return a list instead of bitwise enum (to support more than 32 distinct capabilities)
Capability API to return a list instead of bitwise enum (to support more than 32 distinct capabilities)
RMDA command to quickly and recursively delete a directory from Serv-U FTP GatewayFix: Improve performance of GetFileSize to only switch to Binary for servers that require it
GetFileSize to only switch to Binary for servers that require it
GetFileSize for servers that require itGetListing and GetNameListingFtpClientGetListing if temporary error "Received an unexpected EOF or 0 bytes from the transport stream"Fix: Prefer using Passive/Active modes rather than Enhanced Active/Passive during auto-detection
GetNameListingNew: Automatic FTP connection negotiation using AutoConnect()
AutoConnect()
AutoDetect()FtpProfile.ToCode()FtpExists.NoCheck mode, file size check should not be doneOpenRead with EnableThreadSafeDataConnections always transfers in ASCII (thanks ts678)OpenRead, OpenWrite, OpenAppend (dynamic versions still exist)CalcChmod from FtpClient to FtpExtensions (as part of repository cleanup task)Fix: Async methods do not work with Active FTP mode and SSL/encryption (thanks Mortens4444)
Fix: Divide-by-zero exceptions while calculating progress of file uploads/downloads
Fix: Supress all exceptions when Disposing the underlying FtpSocketStream
Fix: Received an unexpected EOF or 0 bytes from the transport stream (thanks mikemeinz)
UploadFile() progress callback is not called if the file already exists on the serverConnect() method sometimes causes the thread to hang indefinitely (thanks radiy)Nothing published for this version
New: FtpAuthenticationException for authentication errors (thanks erik-wramner)
FtpAuthenticationException for authentication errors (thanks erik-wramner)
New: SSL Buffering is now switchable via the SslBuffering parameter
SslBuffering parameter
FtpClientUserAtHostProxyBlueCoat to FtpClientBlueCoatProxy"Can't find file" to fix FileExists check on some servers (thanks reureu)FileExists and FileExistsAsync methods, added support for FtpReply 550 check (thanks reureu)UploadFile and UploadFileAsync methods, added support for AppendNoCheck handling (thanks reureu)New: Get detailed progress information for uploads/downloads via the FtpProgress object (thanks n0ix)
FtpProgress object (thanks n0ix)
AppendNoCheck and we couldn't read the offset position (thanks @everbalovas)SslStream and BufferedStream so proxied connections with FtpClientHttp11Proxy are to connect (thanks @rmja)New: Additional FTP Server software detection (HP NonStop/Tandem, GlobalScape EFT, Serv-U, Cerberus, CrushFTP, glFTPd)
FileExists returns false if name listing is used and server lists filenames with the pathDownload() methods restartPosition should not be mandatoryNew: Ability to cancel all async methods via CancellationToken (thanks WolfspiritM)
CancellationToken (thanks WolfspiritM)
ReadTimeout is now honored by all async methods (thanks WolfspiritM)New: Ability to resume a download via existsMode on DownloadFile() and DownloadFiles() (thanks n0ix)
existsMode on DownloadFile() and DownloadFiles() (thanks n0ix)
New: OnLogEvent callback to get logs in the context of indivivdual FtpClient connections
OnLogEvent callback to get logs in the context of indivivdual FtpClient connections
FtpClient and then passed to FtpTrace listenersFtpClient argument added to the endBreaking changes to Async API of GetModifiedTime (addition of type argument)
Major release with lots of new and exciting features, and numerous fixes by our contributors. Thanks everyone!
GetListing will manually recurse through directories if FtpListOption.Recursive is set and server does not support recursionLastReply property which returns the last FtpReply recieved from the server.AppendNoCheck to append to a file on the server without checking if it exists (thanks @everbalovas)UploadFileAsync based on fixes already implemented in UploadFileUploadFilesAsync with errorHandling deletes the entire directory instead of specific filesUploadFile() or UploadFiles() sometimes fails to create the remote directory if it doesn't existDownloadDataType Binary value ignored on ASCII-configured FTP serversBufferedStream between SslStream and NetworkStream (thanks @Lukazoid)Dispose method of FTPClient virtual (thanks @martinbu)OpenPassiveDataStream/Async() uses the target FTP host instead of the configured proxy (thanks @rmja)FileExists() for Xlight FTP Server (thanks @oldpepper)IOException on Android (thanks @jersiovic)BeginInvoke calls the callback before the IAsyncResult is added (thanks @Lukazoid)IFtpClientNetworkStream (thanks @iamjay)IFtpClient (thanks @peterfortuin)ActivePorts is specified in active FTP mode (thanks @ToniMontana)OperationCanceledException instead of FtpException when cancellation is requested (thanks @taoyouh)IFtpClient inherit from IDisposable (thanks @repl-andrew-ovens)File.Exists() to run in UI thread (thanks @taoyouh)NetStream was not assigned in FtpSocketStream for .NET Standard in active FTP mode (thanks @ralftar)CurrentDataType was not set for ASCII transfers in DownloadFileAsync/UploadFileAsync (thanks @taoyouh)FtpSocketStream and FtpDataStream are not disposed in FtpSocketStream.Dispose (thanks @taoyouh)UploadFile & DownloadFile methods via IProgressStream.Position should not be set in UploadFileInternal unless supportedUploadFile, DownloadFile, UploadFiles & DownloadFiles (thanks @artiomchi)FileNotFoundException with reference System.Console (thanks @artiomchi)UploadFile or DownloadFile (thanks @artiomchi)Stream.Read (thanks @bgroenks96, @artiomchi, @taoyouh)DownloadFileInternal not recognizing the download data typeEnableThreadSafeConnections (thanks @bgroenks96)IFtpClient interface to build unit tests upon main FtpClient class (thanks Kris0)FtpDataStream reads server reply and closes the underlying stream (thanks Lukazoid)SetModifiedTime API to change modified date of a server file in local timezone/UTCGetModifiedTime, allowing for getting dates in UTC/Local timezoneGetModifiedTime (addition of type argument)GetModifiedTime and SetModifiedTime now honor the TimeOffset property in FtpClientcheckIfFileExists to OpenRead, OpenAppend and OpenWrite to skip GetFileSize checkInnerException is null during a file transfer (upload/download)CreateDirectory and DirectoryExists to allow null/blank input path valuesGetFtpDirectoryName to return correct parent folder of simple folder paths (thanks ww898)Upload, Download, UploadFile(s), DownloadFile(s), GetObjectInfo, DeleteFile, DeleteDirectory, FileExists, DirectoryExists, CreateDirectory, Rename, MoveFile, MoveDirectory, SetFilePermissions, Chmod, GetFilePermissions, GetChmod, GetFileSize, GetModifiedTime, VerifyTransfer, OpenRead, OpenWrite, OpenAppendPlatformUnsupported exception (if you need async you are free to contribute a non-blocking version of the methods)GetListing by reading multiple lines at once (BulkListing property, thanks sierrodc)UploadDataType and DownloadDataType in all sync/async cases (thanks rharrisxtheta)NullReferenceException when arguments are null during FtpTrace.WriteFuncSystem.Threading.Thread for .NET Standard 1.4 version (for UWP)FtpTrace.LogToConsole and LogToFile to control logging in .NET core versionPlainTextEncryption API to support FTPS servers and plain-text FTP firewalls (CCC command)FtpSslStream)FtpTrace.LogFunctions)FtpTrace.LogIP, LogUserName, LogPassword)RecursiveList to control if recursive listing should be usedDeleteDirectory()Fix: UploadFilesAsync with errorHandling deletes the entire directory instead of specific files
UploadFilesAsync with errorHandling deletes the entire directory instead of specific files
Fix: UploadFile() or UploadFiles() sometimes fails to create the remote directory if it doesn't exist
UploadFile() or UploadFiles() sometimes fails to create the remote directory if it doesn't exist
DownloadDataType Binary value ignored on ASCII-configured FTP serversBufferedStream between SslStream and NetworkStream (thanks stengnath)Dispose method of FTPClient virtual (thanks @martinbu)OpenPassiveDataStream/Async() uses the target FTP host instead of the configured proxy (thanks @rmja)FileExists() for Xlight FTP Server (thanks @oldpepper)IOException on Android (thanks @jersiovic)BeginInvoke calls the callback before the IAsyncResult is added (thanks stengnath)Fix: Prevent socket poll from hammering the server multiple times per second
IFtpClientNothing published for this version
Nothing published for this version
Fix: Fix hang in TLS activation because no timeout is set on the underlying NetworkStream (thanks @iamjay)
NetworkStream (thanks @iamjay)Added async versions of FTP methods to IFtpClient (thanks @peterfortuin)
IFtpClient (thanks @peterfortuin)
ActivePorts is specified in active FTP mode (thanks @ToniMontana)OperationCanceledException instead of FtpException when cancellation is requested (thanks taoyouh)Fix: Add support for checking if file exists on Serv-U FTP Server
IFtpClient inherit from IDisposable (thanks @repl-andrew-ovens)File.Exists() to run in UI thread (thanks taoyouh)Fix: When downloading files in ASCII mode, file length is unreliable therefore we read until EOF
NetStream was not assigned in FtpSocketStream for .NET Standard in active FTP mode (thanks @ralftar)CurrentDataType was not set for ASCII transfers in DownloadFileAsync/UploadFileAsync (thanks taoyouh)FtpSocketStream and FtpDataStream are not disposed in FtpSocketStream.Dispose (thanks taoyouh)New Progress reporting for UploadFile & DownloadFile methods via IProgress
UploadFile & DownloadFile methods via IProgress
Stream.Position should not be set in UploadFileInternal unless supportedNew Task-based async methods for .NET Standard and .NET Fx 4.5 (thanks taoyouh)
UploadFile, DownloadFile, UploadFiles & DownloadFiles (thanks artiomchi)FileNotFoundException with reference System.Console (thanks artiomchi)UploadFile or DownloadFile (thanks artiomchi)Stream.Read (thanks bgroenks96, @artiomchi, @taoyouh)DownloadFileInternal not recognizing the download data type
with EnableThreadSafeConnections (thanks bgroenks96)Nothing published for this version
Your coding agent can read these notes before it upgrades. Set up the MCP server →