duplicati/duplicati · warning · UserInformationException
HandleCloseError
HandleCloseError
Error message
Failed to close file handle on CreateFolderAsync with status {status} What it means
Thrown in the CreateFolderAsync finally block when CloseFile on a just-created directory handle returns non-SUCCESS. Reported under code HandleCloseError. The directory may have been created, but the handle did not close cleanly, so resource state is uncertain.
Source
Thrown at Duplicati/Library/Backend/SMB/SMBShareConnection.cs:216
AccessMask.GENERIC_WRITE | AccessMask.SYNCHRONIZE,
FileAttributes.Normal,
ShareAccess.None,
CreateDisposition.FILE_CREATE,
CreateOptions.FILE_DIRECTORY_FILE | CreateOptions.FILE_SYNCHRONOUS_IO_ALERT,
null
);
if (status != NTStatus.STATUS_SUCCESS &&
status != NTStatus.STATUS_OBJECT_NAME_COLLISION) // Ignore if directory already exists
throw new UserInformationException($"{LC.L("Failed to create directory")} {currentPath} with status{status}", "CreateDirectoryError");
}).ConfigureAwait(false);
}
finally
{
if (fileHandle != null)
{
var status = _smbFileStore.CloseFile(fileHandle);
if (status != NTStatus.STATUS_SUCCESS)
throw new UserInformationException($"{LC.L("Failed to close file handle on CreateFolderAsync")} with status {status.ToString()}", "HandleCloseError");
}
}
}
}
finally
{
_semaphore.Release();
}
}
/// <summary>
/// Lists the folder contents of the share and path specified in the connection parameters.
/// </summary>
/// <param name="path">Path to list</param>
/// <param name="cancellationToken">Cancellation Token</param>
/// <exception cref="UserInformationException">Exception to be displayed to user</exception>
public async Task<List<IFileEntry>> ListAsync(string path, CancellationToken cancellationToken)
{View on GitHub (pinned to 3f348be3e3)
Solutions
- Verify the directory was actually created via GetEntryAsync before treating the error as fatal.
- Retry CreateFolderAsync once; COLLISION handling makes it idempotent for existing segments.
- Reconnect the SMB session if close failures persist (the session may be broken).
- Update/inspect the target server for known close-status bugs if it is reproducible.
Example fix
// before: a close error aborts the whole folder creation
await conn.CreateFolderAsync(path, ct);
// after: tolerate a close error if the directory now exists
try { await conn.CreateFolderAsync(path, ct); }
catch (UserInformationException ex) when (ex.HelpID == "HandleCloseError")
{ if (await conn.GetEntryAsync(path.TrimEnd('/') + "/", ct) is null) throw; } Defensive patterns
Strategy: try-catch
Validate before calling
// after a create+close, confirm the directory now exists
var ok = await conn.GetEntryAsync(currentPath.TrimEnd('/') + "/", ct); Type guard
static bool IsHandleCloseError(UserInformationException e) => e.HelpID == "HandleCloseError";
Try / catch
try { await conn.CreateFolderAsync(path, ct); }
catch (UserInformationException ex) when (ex.HelpID == "HandleCloseError")
{ if (await conn.GetEntryAsync(path.TrimEnd('/') + "/", ct) is { IsFolder: true }) return; throw; } Prevention
- Treat a HandleCloseError in CreateFolder as possibly-succeeded; verify.
- CreateFolderAsync tolerates STATUS_OBJECT_NAME_COLLISION, so retrying is safe.
- Reconnect if close errors persist.
When it happens
Trigger: After a CreateFile for a directory segment, the finally block calls _smbFileStore.CloseFile(fileHandle) and gets a status other than STATUS_SUCCESS.
Common situations: Transient network drop during the close; server under load; handle already torn down by a transport reset; recurring server firmware/driver bug returning non-SUCCESS on directory closes.
Related errors
AI-assisted analysis of duplicati/duplicati@3f348be3e3 (2026-08-13).
Data as JSON: /api/errors/88e0d79d469712fc.
Report an issue: GitHub.