{"record":{"id":"88e0d79d469712fc","repo":"duplicati/duplicati","slug":"handlecloseerror","errorCode":"HandleCloseError","errorMessage":"Failed to close file handle on CreateFolderAsync with status {status}","messagePattern":"Failed to close file handle on CreateFolderAsync with status (.+?)","errorType":"exception","errorClass":"UserInformationException","httpStatus":null,"severity":"warning","filePath":"Duplicati/Library/Backend/SMB/SMBShareConnection.cs","lineNumber":216,"sourceCode":"                            AccessMask.GENERIC_WRITE | AccessMask.SYNCHRONIZE,\n                            FileAttributes.Normal,\n                            ShareAccess.None,\n                            CreateDisposition.FILE_CREATE,\n                            CreateOptions.FILE_DIRECTORY_FILE | CreateOptions.FILE_SYNCHRONOUS_IO_ALERT,\n                            null\n                        );\n                        if (status != NTStatus.STATUS_SUCCESS &&\n                            status != NTStatus.STATUS_OBJECT_NAME_COLLISION) // Ignore if directory already exists\n                            throw new UserInformationException($\"{LC.L(\"Failed to create directory\")} {currentPath} with status{status}\", \"CreateDirectoryError\");\n                    }).ConfigureAwait(false);\n                }\n                finally\n                {\n                    if (fileHandle != null)\n                    {\n                        var status = _smbFileStore.CloseFile(fileHandle);\n                        if (status != NTStatus.STATUS_SUCCESS)\n                            throw new UserInformationException($\"{LC.L(\"Failed to close file handle on CreateFolderAsync\")} with status {status.ToString()}\", \"HandleCloseError\");\n                    }\n                }\n            }\n        }\n        finally\n        {\n            _semaphore.Release();\n        }\n    }\n\n    /// <summary>\n    /// Lists the folder contents of the share and path specified in the connection parameters.\n    /// </summary>\n    /// <param name=\"path\">Path to list</param>\n    /// <param name=\"cancellationToken\">Cancellation Token</param>\n    /// <exception cref=\"UserInformationException\">Exception to be displayed to user</exception>\n    public async Task<List<IFileEntry>> ListAsync(string path, CancellationToken cancellationToken)\n    {","sourceCodeStart":198,"sourceCodeEnd":234,"githubUrl":"https://github.com/duplicati/duplicati/blob/3f348be3e33f5d72d414e3ad55839c2ba34dda67/Duplicati/Library/Backend/SMB/SMBShareConnection.cs#L198-L234","documentation":"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.","triggerScenarios":"After a CreateFile for a directory segment, the finally block calls _smbFileStore.CloseFile(fileHandle) and gets a status other than STATUS_SUCCESS.","commonSituations":"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.","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."],"exampleFix":"// before: a close error aborts the whole folder creation\nawait conn.CreateFolderAsync(path, ct);\n\n// after: tolerate a close error if the directory now exists\ntry { await conn.CreateFolderAsync(path, ct); }\ncatch (UserInformationException ex) when (ex.HelpID == \"HandleCloseError\")\n{ if (await conn.GetEntryAsync(path.TrimEnd('/') + \"/\", ct) is null) throw; }","handlingStrategy":"try-catch","validationCode":"// after a create+close, confirm the directory now exists\nvar ok = await conn.GetEntryAsync(currentPath.TrimEnd('/') + \"/\", ct);","typeGuard":"static bool IsHandleCloseError(UserInformationException e) => e.HelpID == \"HandleCloseError\";","tryCatchPattern":"try { await conn.CreateFolderAsync(path, ct); }\ncatch (UserInformationException ex) when (ex.HelpID == \"HandleCloseError\")\n{ if (await conn.GetEntryAsync(path.TrimEnd('/') + \"/\", ct) is { IsFolder: true }) return; throw; }","preventionTips":["Treat a HandleCloseError in CreateFolder as possibly-succeeded; verify.","CreateFolderAsync tolerates STATUS_OBJECT_NAME_COLLISION, so retrying is safe.","Reconnect if close errors persist."],"tags":["smb","directory","close","handle"],"backgroundTag":null,"analyzedSha":"3f348be3e33f5d72d414e3ad55839c2ba34dda67","analyzedAt":"2026-08-13T16:48:27.008Z","schemaVersion":2},"datasetVersion":"2026-08-13T19:17:28.613Z"}