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 21 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: FluentFTP is now fully AOT ready! This means you can use FluentFTP in projects that use Native Ahead-of-Time (AOT) compilation
Logger, ValuePrinter, FtpAutoDetectConfig, FtpSslStream)FluentFTP.AotExamples)FluentFTP.Tests.Integration NSFluentFTP.Tests.Unit.BouncyCastle NSFix: Race condition when connectEvent accessed after FtpSocketStream is disposed
connectEvent accessed after FtpSocketStream is disposedFEAT check to assume EPSV is supported by defaultOne column per quarter.
New: SanitizeMode Properties to configure type of FTP path sanitization. Sanitizer can be disabled, or throw exceptions, or silently rename FTP paths.
SanitizeMode Properties to configure type of FTP path sanitization. Sanitizer can be disabled, or throw exceptions, or silently rename FTP paths.FtpSanitizeException with properties describing the type of sanitization issue, and recommended fixes.DownloadUriBytes overloads.AsyncFtpClient.Connect ignores pre-cancelled CancellationToken.WriteTimeout setting to control timeout for FTP write operationsTrackConfigChanges in FTP stream write operations to update stream config based on changed client config. Config changes like timeouts will be applied before the next read/write operation.Improve error handling during FTP connection to fix intermittent hanging on Xamarin
LogVersion in Logger for Mono/XamarinCancellationTokenSource affecting AsyncFtpClient and GnuTLSFtpProfile.ToCode to generate encoding code correctlyFix: Copy missing properties in FtpConfig.CopyTo
FtpConfig.CopyToNew: SanitizeControlChars, SanitizeMultiline, SanitizeUnicodeSpoofing, SanitizeTraversal and SanitizeUrlEncoding Properties to configure FTP path sani
SanitizeControlChars, SanitizeMultiline, SanitizeUnicodeSpoofing, SanitizeTraversal and SanitizeUrlEncoding Properties to configure FTP path sanitization at a granular levelSanitizerModuleTimeZone and LocalTimeZonePathInsecureTests to ensure that the sanitizer is disabled based on config propertiesChange: Allowed the & character in filenames by default
& character in filenames by defaultNullReferenceException in FTPS disconnect when accessing SslSessionLengthNew: Secure FTP path sanitizer to protect against FTP command injection, traversal, encoding bypasses, and parser confusion attacks
Execute APICreateDirectory, DeleteDirectory, DeleteFile, DirectoryExists, DownloadBytes, DownloadDirectory, DownloadFile, DownloadStream, EmptyDirectory, FileExists, GetChecksum, GetFilePermissions, GetFileSize, GetListing, GetModifiedTime, GetNameListing, GetObjectInfo, MoveDirectory, MoveFile, OpenAppend, OpenRead, OpenWrite, Rename, SetFilePermissions, SetModifiedTime, SetWorkingDirectory, TransferDirectory, TransferFile, UploadBytes, UploadDirectory, UploadFiles, UploadStream, CompareFileGetFtpPath to SanitizeFtpPath to better convey its intended functionGetFtpPath to AppendFtpPath to better convey its intended functionConfigureAuthentication event handler to FTP clients to customize SslClientAuthenticationOptions before TLS handshake and enable support for Linux for legacy FTPS serversSslClientAuthenticationOptions pattern in both synchronous and async methodsNothing published for this version
Nothing published for this version
Fix missing await and async in Async GetReply
GetReplyAsyncFtpMonitor.StartTimerAsyncFtpMonitor and FtpMonitor access modifiers to virtual for easy overridingNew: Handle no-reply from FTP server by adding new overload to Execute() (thanks @FanDjango)
Execute() (thanks @FanDjango)NetworkStream ReadAsync infinite timeout when server is unresponsive (thanks @Gino1024)Config.PreserveTrailingSlashCmdList setting (thanks @FanDjango)GetChecksum() cannot parse FTP server response if the path contains spaces (thanks @FanDjango)Config.EncryptAuthenticationOnly (thanks @FanDjango)NotImplementedException (thanks @FanDjango)OperationCancelledException is thrown when cancelling a AsyncConnect() (thanks @bruinsg)FakeAsyncFtpClient and FakeFtpClient)Task.Delay instead of Thread.Sleep (thanks @jnyrup)CancellationToken.Register with async delegate (thanks @jnyrup)Nothing published for this version
Add SslProtocol and SslCipherSuite properties.
SslProtocol and SslCipherSuite properties.HashAlgorithms is readFtpSelfConnectMode to control how FTP reconnections are handledFileTransferTestsNew: Time Zone conversion is performed using standard .NET TimeZoneInfo instead of hourly offset values
TimeZoneInfo instead of hourly offset valuesClientTimeZone and ServerTimeZone Properties to configure Time Zone conversionSetClientTimeZone and SetServerTimeZone Utility methods to configure Time Zone conversionFtpMonitor, AsyncFtpMonitor, BlockingAsyncFtpMonitor)FtpMonitorEventArgs)BlockingAsyncFtpMonitorDownloadFileInternal and UploadFileInternal)LogMaskModule throwing exception when UserName is empty (thanks @ssg)AsyncFtpClient dispose logic and cleanup warnings on build (thanks @FanDjango)Nothing published for this version
Fix: GUI hangs during Dispose of AsyncFtpClient
Dispose of AsyncFtpClientFtpCapability.MLSD to MLST to better reflect its behaviourNew: Accurate FTP connection status tracking with the help of NoopDaemon (integrated into IsConnected API)
NoopDaemon (integrated into IsConnected API)FtpConnectionState to track FTP socket connection statePoll calls550 when folder exists but is emptyAsMemory API for reading/writing data from/to the FTP socket stream in .NET 5+Config.SocketPollInterval setting, because it is no longer used or requiredGetReply core functionExecute APIFtpSocketStreamNew: FtpRemoteExists.OverwriteInPlace mode which overwrites files without deleting them first
FtpRemoteExists.OverwriteInPlace mode which overwrites files without deleting them firstFtpConfig.PostConnect to enable the init sequence performed immediately after connectionBufferedStream feature and further refactoring of Dispose logicAuthenticateAsClient API rather than outdated APIConfig.LogHost is set to falseDateTimes.ParseFtpDate will consider provided formats when parsing date/time valuesFix: Correct sequencing of FTP stream disposing for .NET Framework
GetReply call in UploadInternal/DownloadInternalFile Verification (thanks DasRaschloch and FanDjango)
DownloadDirectory, DownloadFile, DownloadFiles, support new size/checksum/date comparisonUploadDirectory, UploadFile, UploadFiles support new size/checksum/date comparisonTransferDirectory, TransferFile support new size/checksum/date comparisonFtpVerify has new options: Size/Date/Checksum/OnlyChecksumDownloadFile with Progress throws FtpExceptionUploadInternal/DownloadInternalGetFileSize provides invalid file length and transfer failsGetListing does not use the proxy with passive FTPBaseClient is also IAsyncDisposable in addition to IDisposableAsyncFtpClient throws non-fatal InvalidCastExceptionAsyncFtpClient throws non-fatal InvalidCastExceptionAsyncFtpClient to change all Close usage to await CloseAsyncFtpDataStream now supports an async close methodDisposeAsync pattern for AsyncFtpClientDispose/DisposeAsync on BufferedStream instead of Flush/FlushAsyncFtpSslStream for graceful TLS terminationFix: Handle NOOP API exceptions
Execute APIGetReply logging and handling for stale data and NOOP reactionsIsStillConnected: Clean up Connect/DisconnectInternal interface artifactsIsStillConnected: Add log messagesSITE LISTFMT 1 and SITE NAMEFMT 1 on connectDownloadFile: FileCount Progress updated even when files are skipped (thanks J0nathan550)DownloadFile: stopPosition not working in some cases (thanks alexgubanow)DownloadFile: Progress calculation not correct when using stopPosition (thanks alexgubanow)Fix: Change semaphore logic to prevent deadlock in NOOP Daemon (thanks FanDjango)
New: Revised NOOP handling with new config option Noop to enable NOOP daemon
Noop to enable NOOP daemonNoopInactiveCommands and NoopActiveCommands to set FTP commands usableNoopTestConnectivity to issue NOOP commands before every FTP commandNoopInterval now has a default of 3 minutesGetReply for new NOOP handling logicIsStillConnected() API to reliably check if FTP connection is still activeAutoDetect as failed detection instead of aborting (thanks FabBadDog)AutoDetect is thread unsafe, fix AutoDetectConfig IncludeImplicit logicFtpClientGetListing() commandOpenRead retry attempt fails due to typoDisableUTF8 APINET50_OR_LATER invalid moniker (thanks sean-bloch)OpenAppend, OpenRead and OpenWrite to help in debuggingNew: FtpResult.ToStatus() API to easily compare result values of DownloadFile/DownloadFiles and UploadFile/UploadFiles
FtpResult.ToStatus() API to easily compare result values of DownloadFile/DownloadFiles and UploadFile/UploadFilesCreateDirectory sometimes needed in AutoNavigate modeCWD/PWD directory navigation in AutoNavigate mode450 error for empty foldersNothing published for this version
Directory Navigation (thanks FanDjango)
GetCheckSumUploadDirectory with FtpNavigate.Conditional does not auto-navigate correctlyDownloadFile, UploadFile, GetListingNew: Navigate Config setting to automatically handle FTP directory navigation
Navigate Config setting to automatically handle FTP directory navigationNavigate settingGetListing API honors Navigate settingDownloadUriBytes API method to directly connect and download a URI/URLOpenRead, OpenWrite and OpenAppend quirks to handle their stale dataCheckStaleData implementationAutoDetect with object-driven configuration using FtpAutoDetectConfigRequireEncryption and IncludeImplicit to AutoDetect to allow for more configurability during auto-connectionAutoDetect behaviour to support various server use-casesRNFM/RNTO FTP commands to critical-sequence list to fix Auto-Reconnect of SSL sessionsAutoDetect empty config is gracefully handledNothing published for this version
New: Add exact .NET platform build target during the version logging
LocalFileShareOption to allow setting file sharing mode for uploadsPASVUSE aka PassiveAllowUnroutableAutoActive and PassiveExtendedFtpSslStreamShutDownAsync for .NET 4.7 and laterInnerException does not get caught during FTPS security exceptionPolicyErrors not being set correctlyInfoMessages (thanks jnyrup)GnuTlsStream integration tests due to invalid stream detectionFix: Custom stream logging tweak: Message first then close stream
InnerException if it exists within the exceptionExecute API methodsFix: Hotfix to remove new DowloadStream overload that causes compile failure
DowloadStream overload that causes compile failureNew: Add stopPosition parameter to DownloadBytes and DowloadStream to allow partial downloads
stopPosition parameter to DownloadBytes and DowloadStream to allow partial downloadsNew: Add 9 missing properties to the FTP client interfaces
New: DiscoverSslSessionLength API to auto compute a working value for SSL Session length (thanks FanDjango)
DiscoverSslSessionLength API to auto compute a working value for SSL Session length (thanks FanDjango)API: Rename ExecuteGetText to ExecuteDownloadText
ExecuteGetText to ExecuteDownloadTextAsyncFtpClient.CreateDirectory fails on freshly created client instance (thanks FanDjango)Nothing published for this version
New: ExecuteGetText API to execute an FTP command and return multiline output (thanks FanDjango)
ExecuteGetText API to execute an FTP command and return multiline output (thanks FanDjango)FluentFTP.GnuTLS NuGet package to allow for GnuTLS TLS 1.3 streamsNothing published for this version
Nothing published for this version
New: UploadFiles API in AsyncFtpClient which takes an IEnumerable
UploadFiles API in AsyncFtpClient which takes an IEnumerable<FileInfo>UploadFiles and DownloadFiles now support rules which allow filtering of uploaded/downloaded filesUploadFiles and DownloadFiles now return a List<FtpResult> with per-file status rather than just a countFtpMissingObjectException thrown when trying to download a non-existant objectDownloadDirectory, DownloadFile, DownloadBytes, DownloadStream will throw FtpMissingObjectException rather than silently failingDownloadFiles will mark non-existant files as IsFailed and add the Exception rather than silently failingExecute logic to handle working directory on automatic reconnection (thanks FanDjango)Info to Warn (thanks FanDjango)ConnectAsync for net472 platform where required (thanks jnyrup)Config.LogDurations to configure if durations are to be loggedResponse log message (thanks FanDjango)when keyword and new conditional keywords (thanks jnyrup)Nothing published for this version
Nothing published for this version
Please read the Migration Guide for help migrating to the new version!
FtpClient.Logger is no longer a MELA ILoggerFtpClient.Logger is now a custom interface called IFtpLoggerNew: Save bandwidth on automatic reconnection by skipping FEAT command
FEAT commandValidateCertificate handler if none is providedSetModifiedTime falls back to MDTM if MFMT command not availableGetListing: Catch control connection loss and retry onceGetListing silently fails and returns empty array if connection lostNew: Detect Apache FTP Server (allows for future server-specific handling)
Config.SslSessionLength setting to perform automatic reconnection to bypass SSL issuesReadStaleData and moved into ExecuteIOException edge case on FTPS connections after a certain number of FTP commands226 Transfer complete edge case in FTP file downloadFtpRemoteExists.NoCheck mode in MoveFile to prevent checking for existing filesNew: DNS Caching to prevent DNS server rejecting name resolution for rapidly repeating requests
FtpException thrown when creating directoriesCWD command sentAutoConnect fails with Azure FTP servers due to profile handlingInvalidOperationException if unable to connectConnect APIConnectTimeout is not taking effect for ConnectAsync APICurrentDataType when re-connected to an FTP serverAggregateException where requiredResumeUpload for synchronous APINew: TLS authentication failures will always throw AuthenticationException (thanks FanDjango)
Please read the Migration Guide for help migrating to the new version!
LastReplies property to fetch a list of the last 5 server replies (thanks FanDjango)Config.DisconnectWithShutdown as it was not required (thanks FanDjango)FtpListOption.NoImage as it was not required (thanks FanDjango)CurrentDataType and remove ForceSetDataType (thanks FanDjango)Config.DisconnectWithShutdown (thanks FanDjango)GetReply redesign: New mode to exhaustively read all NOOP replies (thanks FanDjango)Please read the Migration Guide for help migrating to the new version!
EmptyDirectory API to delete files but leave top-level directory intact (thanks FanDjango)AutoConnectFtpProtocolUnsupportedException if the FTP server is forcing TLS 1.3 connectionsNOOP handling (thanks FanDjango)NOOP command after uploading files to resolve issues (thanks FanDjango)CancellationToken within DownloadFile, UploadFile, TransferDirectory, DeleteFile, OpenRead, OpenAppend (thanks jnyrup)SIZE command usage for UploadFile in NoCheck and OverWrite modes (thanks FanDjango)ActivePorts in FTP Active connection mode (thanks FanDjango)Please read the Migration Guide for help migrating to the new version!
FtpClient and AsyncFtpClientIFtpClient and IAsyncFtpClientBaseFtpClientAsync suffix for all async FTP methods in AsyncFtpClientclient.Config objectFtpConfig to cleanup client APIclient.OnLogEvent and FtpTrace systemclient.Logger using industry-standard ILogger interfaceMicrosoft.Extensions.Logging.Abstractions v2.1.0OnLogEvent is now renamed to LegacyLoggerLogIP renamed to LogHostLogFunctions as it is always enabledFtpClient*Proxy and AsyncFtpClient*ProxyFluentFTP.Proxy.SyncProxy and FluentFTP.Proxy.AsyncProxy NSHandshakeAsync in async FTP proxies (thanks jnyrup)AsyncFtpClientIInternalFtpClient.editorconfig to prevent using IDE defaults (thanks jnyrup)FtpClient.Connect and FtpClient.GetPublicIPDereferenceLink and DereferenceLinkAsyncQuickTransferLimit, MaximumDereferenceCount, EnableThreadSafeDataConnections, PlainTextEncryptionFtpListOption.DerefLinksGetHashAlgorithm, SetHashAlgorithm, GetHash, etcIAsyncResultAuthenticate (thanks FanDjango)FtpListParser, FtpClientState, FtpFxpSession, FtpFxpSessionAsync, FtpListItem, FtpProfile, FtpResultFtpFileExtensionRule, FtpFileNameRegexRule, FtpFileNameRule, FtpFolderNameRegexRule, FtpFolderNameRule, FtpSizeRuleNothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
New: Add SslProtocolActive property to retrieve the negotiated SSL/TLS protocol version
SslProtocolActive property to retrieve the negotiated SSL/TLS protocol versionGetListing (thanks FanDjango)GetListingAsyncEnumerable (thanks tommysor)New: Detect D-Link, TP-LINK, Huawei, MicroTik FTP servers (allows for future server-specific handling)
AutoConnect now correctly handles internal AggregateException (.NET 5.0+)AutoConnect now correctly connects to servers requiring TLS 1.2New: Add 5 missing methods into the IFtpClient interface
IFtpClient interfaceGetListing absolute path conversionNew: GetListingAsyncEnumerable method to get file listing using IAsyncEnumerable pattern
GetListingAsyncEnumerable method to get file listing using IAsyncEnumerable patternAutoConnect, throw FtpProtocolUnsupportedException if newer .NET requiredAutoConnect (.NET 5.0+)Your coding agent can read these notes before it upgrades. Set up the MCP server →