files-community/Files · error · IOException
Failed to connect to FTP server.
Error message
Failed to connect to FTP server.
What it means
Thrown by FtpStorageFolder.CreateFolderAsync (Files.App/Utils) when EnsureConnectedAsync returns false - the client could not connect. Identical root cause to error 10 but on the folder-creation path; runs inside SafetyExtensions.Wrap with RetryWithCredentialsAsync.
Source
Thrown at src/Files.App/Utils/Storage/StorageItems/FtpStorageFolder.cs:241
throw new FileAlreadyExistsException(desiredName);
return null;
}
throw new IOException($"Failed to create file {remotePath}.");
}, ((IPasswordProtectedItem)this).RetryWithCredentialsAsync));
}
public override IAsyncOperation<BaseStorageFolder> CreateFolderAsync(string desiredName)
=> CreateFolderAsync(desiredName, CreationCollisionOption.FailIfExists);
public override IAsyncOperation<BaseStorageFolder> CreateFolderAsync(string desiredName, CreationCollisionOption options)
{
return AsyncInfo.Run((cancellationToken) => SafetyExtensions.Wrap<BaseStorageFolder>(async () =>
{
using var ftpClient = GetFtpClient();
if (!await ftpClient.EnsureConnectedAsync())
{
throw new IOException($"Failed to connect to FTP server.");
}
string fileName = $"{FtpPath}/{desiredName}";
if (await ftpClient.DirectoryExists(fileName))
{
var item = new FtpStorageFolder(new StorageFileWithPath(null, fileName));
((IPasswordProtectedItem)item).CopyFrom(this);
return item;
}
bool replaceExisting = options is CreationCollisionOption.ReplaceExisting;
bool isSuccessful = await ftpClient.CreateDirectory(fileName, replaceExisting, cancellationToken);
if (!isSuccessful)
{
throw new IOException($"Failed to create folder {desiredName}.");
}
var folder = new FtpStorageFolder(new StorageFileWithPath(null, $"{Path}/{desiredName}"));View on GitHub (pinned to 68c68a58d4)
Solutions
- Trigger the credentials retry path (RetryWithCredentialsAsync) to re-prompt the user.
- Verify host/port/encryption configuration matches the server.
- Check network and firewall reachability to the FTP control and passive data ports.
- Catch IOException and classify it as a connection failure for user messaging.
- Recreate the folder handle from a fresh connection if the client is stale.
Defensive patterns
Strategy: retry
Validate before calling
// Confirm connectivity before creating the folder.
using var c = GetFtpClient();
if (!await c.EnsureConnectedAsync())
throw new IOException("Cannot reach FTP server; check credentials and network."); Try / catch
try { await folder.CreateFolderAsync(name, options); }
catch (IOException ex) when (ex.Message.Contains("connect to FTP"))
{ /* re-prompt credentials, then retry */ } Prevention
- Re-prompt credentials via the RetryWithCredentialsAsync hook.
- Verify host/port/encryption configuration.
- Confirm firewall allows control and passive data ports.
When it happens
Trigger: CreateFolderAsync where EnsureConnectedAsync fails before the DirectoryExists/CreateDirectory calls. Wrong credentials, unreachable host, blocked port, or failed TLS handshake.
Common situations: Expired stored password; server downtime; firewall blocking control/data ports; cert trust change; stale client in a pool.
Related errors
- Directory was not successfully created.
- Failed to connect to FTP server.
- Failed to create folder {desiredName}.
- File creation failed.
- Directory already exists.
AI-assisted analysis of files-community/Files@68c68a58d4 (2026-08-13).
Data as JSON: /api/errors/fe1e5088bbf1dace.
Report an issue: GitHub.