files-community/Files · error · IOException

Failed to create folder {desiredName}.

Error message

Failed to create folder {desiredName}.

What it means

Thrown by FtpStorageFolder.CreateFolderAsync (Files.App/Utils) when AsyncFtpClient.CreateDirectory returns false. The directory could not be created at {FtpPath}/{desiredName}: usually a missing parent directory (FTP MKD is non-recursive), lack of create permission, invalid name, or the server rejecting the operation.

Source

Thrown at src/Files.App/Utils/Storage/StorageItems/FtpStorageFolder.cs:256

				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}"));
				((IPasswordProtectedItem)folder).CopyFrom(this);
				return folder;
			}, ((IPasswordProtectedItem)this).RetryWithCredentialsAsync));
		}

		public override IAsyncOperation<BaseStorageFolder> MoveAsync(IStorageFolder destinationFolder)
			=> MoveAsync(destinationFolder, NameCollisionOption.FailIfExists);
		public override IAsyncOperation<BaseStorageFolder> MoveAsync(IStorageFolder destinationFolder, NameCollisionOption option)
		{
			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.");

View on GitHub (pinned to 68c68a58d4)

Solutions

  1. Create parent directories first, or use a recursive create that forces intermediate directory creation.
  2. Sanitize the desired name for the target server's filesystem.
  3. Check ftpClient.LastReply for the MKD failure code and report it.
  4. Confirm the FTP account has directory-creation rights on the target.
  5. Catch IOException and retry once after ensuring the parent exists.

Example fix

// before
bool isSuccessful = await ftpClient.CreateDirectory(fileName, replaceExisting, cancellationToken);

// after
bool isSuccessful = await ftpClient.CreateDirectory(fileName, replaceExisting || forceParents: true, cancellationToken);
if (!isSuccessful)
    throw new IOException($"Failed to create folder {desiredName}: {ftpClient.LastReply?.Code} {ftpClient.LastReply?.Message}");
Defensive patterns

Strategy: try-catch

Validate before calling

// Ensure the parent directory exists before creating a nested folder.
if (!await ftpClient.DirectoryExists(FtpPath, ct))
    await ftpClient.CreateDirectory(FtpPath, true, ct);

Try / catch

try { return await folder.CreateFolderAsync(name, options); }
catch (IOException ex) when (ex.Message.Contains("Failed to create folder"))
{ var reply = ftpClient.LastReply; /* inspect and report MKD failure */ throw; }

Prevention

When it happens

Trigger: CreateDirectory(fileName, replaceExisting, ct) returning false after a successful connection and after the DirectoryExists early-return did not apply. Missing parent is the most common cause when creating nested paths in one step.

Common situations: Creating nested folders without creating parents first; accounts restricted below the target; names with illegal characters; servers that disallow overwriting an existing directory.

Related errors


AI-assisted analysis of files-community/Files@68c68a58d4 (2026-08-13). Data as JSON: /api/errors/da33f12835f89ce8. Report an issue: GitHub.