Skip to content

Renci.SshNet.Common.SshException: Failure. exception #582

Closed

Description

@ybkamath

Hello,

I have been using the Renci SSH.NET(2016.1.0.0) NuGet package in my web api code, to transfer files from server to a remote SFTP server. This has been working very well for me. The issue I am facing is that I am getting the error marked below. My .NET framework version is 4.6

An exception has been caught during the file upload..:Renci.SshNet.Common.SshException: Failure.
at Renci.SshNet.Sftp.SftpSession.RequestOpen(String path, Flags flags, Boolean nullOnError)
at Renci.SshNet.SftpClient.InternalUploadFile(Stream input, String path, Flags flags, SftpUploadAsyncResult asyncResult, Action1 uploadCallback) at Renci.SshNet.SftpClient.UploadFile(Stream input, String path, Action1 uploadCallback)
at BASF.TAR.RMSService.Controllers.AttachmentController.Get(String sourcepaths, String destinationpath) in d:\Projects\TAR\Samples\BASF.TAR.RMSService\BASF.TAR.RMSService\Controllers\AttachmentController.cs:line 47

I am using the code in my controller as below, its a simple function that takes a source path which is pipe seperated strings and a destination path which is the path on the remote FTP server. The client opens the connection to the server and then in a loop manner each file is uploaded to the remote server and the log is printed.

Please can you let me know why this error is occuring sometimes, any help would be greatly appreciated

public IHttpActionResult Get([FromUri]string sourcepaths, string destinationpath)
        {
            var fileInfo = new List<string>();

            log.Info("Entering the Put() method of the AttachmentController class..");
            try
            {
                using (SftpClient sftp = new SftpClient(ConfigurationManager.AppSettings["SFTP"].ToString(), Convert.ToInt32(ConfigurationManager.AppSettings["Port"].ToString()), ConfigurationManager.AppSettings["UserId"].ToString(), ConfigurationManager.AppSettings["Password"].ToString()))
                {
                    try
                    {
                        if (string.IsNullOrEmpty(sourcepaths) && string.IsNullOrEmpty(destinationpath)) return Ok();

                        var filePaths = sourcepaths.Split('|');
                        sftp.Connect();
                        log.InfoFormat("Connected to SFTP server:{0}..", ConfigurationManager.AppSettings["SFTP"].ToString());
                        
                        log.InfoFormat("Original destination path:{0}", destinationpath);
                        log.InfoFormat("Upload path in the sftp location:{0}", OriginalAttPathToFileSharePath(destinationpath.ToLower()));

                        log.Info("Uploading file...");

                        sftp.ChangeDirectory(OriginalAttPathToFileSharePath(destinationpath.ToLower()));
                        log.InfoFormat("Original destination path:{0}", destinationpath);
                        log.InfoFormat("Upload path in the sftp location:{0}", OriginalAttPathToFileSharePath(destinationpath.ToLower()));
                        foreach (var file in filePaths)
                        {
                            log.InfoFormat("File to be uploaded:{0}", file);
                            using (var stream = new FileStream(file, FileMode.Open, FileAccess.ReadWrite, FileShare.ReadWrite))
                            {
                                sftp.UploadFile(stream, Path.GetFileName(file), (o) =>
                                {
                                    Console.WriteLine(o);
                                });
                            }
                        }
                        log.Info("File uploaded to server...");
                        sftp.Disconnect();
                    }
                    catch (Exception e)
                    {
                        log.ErrorFormat("An exception has been caught during the file upload..:{0}", e);
                    }
                }
            }
            catch (Exception exp)
            {
                log.Error("Error occured in the Put() method of the AttachmentController class..", exp);
            }
            log.Info("Exiting the Put() method of the AttachmentController class..");
            return Ok();
        }

Activity

  1. worldbeater commented on Aug 19, 2019

    @worldbeater

    Just faced the same issue on Windows with OpenSSH client and server, installed according to Microsoft documentation which comes from here https://docs.microsoft.com/en-us/windows-server/administration/openssh/openssh_install_firstuse OpenSSH client comes as a default Windows capability, and OpenSSH server was installed using a Powershell script as such:

    Get-WindowsCapability -Online | ? Name -like 'OpenSSH*'
    Add-WindowsCapability -Online -Name OpenSSH.Server~~~~0.0.1.0
    Start-Service sshd

    Got the exception while attempting to call the following code (.NET Core 2.1, SSH.NET 2016.1.0):

    sftp.DownloadFile(from, stream);

    Exception stack trace:

    Renci.SshNet.Common.SshException: Failure
       at Renci.SshNet.Common.AsyncResult.EndInvoke()
       at Renci.SshNet.Sftp.SftpSession.EndOpen(SftpOpenAsyncResult asyncResult)
       at Renci.SshNet.ServiceFactory.CreateSftpFileReader(String fileName, ISftpSession sftpSession, UInt32 bufferSize)
       at Renci.SshNet.SftpClient.InternalDownloadFile(String path, Stream output, SftpDownloadAsyncResult asyncResult, Action`1 downloadCallback)
       at Renci.SshNet.SftpClient.DownloadFile(String path, Stream output, Action`1 downloadCallback)
       at RapiAgent.Rpc.RapiSftpRpc.Download(String from, String to, RapiSftpCredentials credentials) in Example.cs:line 21
       at CoreRPC.RequestHandler.CoreRPC.Transport.IRequestHandler.HandleRequest(IRequest req)
    

    Note, that a similar CLI-based operation completes successfully:

    sftp <from-path> <to-path>

    Seems that we have to debug SSH.NET on our own due to a few curious SSH.NET design decisions leading to SFTP error codes getting swallowed. Will write back in case if I manage to figure out the issue, but any ideas would be really appreciated.

  2. worldbeater commented on Aug 20, 2019

    @worldbeater

    Well, I think I've figured out why this is happening to us. If I attempt to use the SSH.NET library on a Windows machine while targeting .NET Core netcoreapp2.1 (not sure, probably .NET Core support is at experimental stage for SSH.NET now), my absolute paths get misinterpreted.

    The following line seems to be the cause:

    var fullPath = _sftpSession.GetCanonicalPath(path);

    For example, the following absolute Windows path: C:\Users\usr\AppData\Local\Temp\example_in
    Gets transformed into the following: /C:/Users/usr/C:/Users/usr/AppData/Local/Temp/example_in

    Yeah, /C:/Users/usr repeats twice, and this isn't a typo! The only way to fix the issue above is to fork the SSH.NET repository, and to replace the line referenced above with somewhat like the following: var fullPath = path; However, this works only for absolute paths, but this was enough in my case.

    UPD

    Ahh, found another neater way to resolve the issue, all we need to do is to turn the following:

    // Breaks with Renci.SshNet.Common.SshException: Failure
    sftp.DownloadFile("C:\Users\usr\AppData\Local\Temp\example_in", stream);

    Into the following:

    // Completes normally.
    sftp.DownloadFile("/C:/Users/usr/AppData/Local/Temp/example_in", stream);

    And so it works, the same applies to UploadFile too.

    // With input like the following path:
    // C:\Users\usr\AppData\Local\Temp\example_in
    // The snippet below won't throw.
    var path = $"/{from.Replace(@"\", "/")}";
    sftp.DownloadFile(path, stream);
  3. ybkamath commented on Aug 21, 2019

    @ybkamath
    Author

    Thanks @worldbeater Let me try this solution and get back to you,

  4. ybkamath commented on Aug 21, 2019

    @ybkamath
    Author

    @worldbeater might be a stupid question but in the file upload we pass the file name instead of the path, can you let me know on that please

  5. worldbeater commented on Aug 21, 2019

    @worldbeater

    @ybkamath if you pass the file name to DownloadFile or to UploadFile, then it will be treated as a relative path I suppose. Worth inspecting which absolute path SSH.NET constructs from a relative path by building the repo from sources and referencing it like:

    <ProjectReference Include="..\Renci.SshNet.NETCore\Renci.SshNet.NETCore.csproj" />

    Then set a breakpoint here:

    var fullPath = _sftpSession.GetCanonicalPath(path);
    Another option is to copy-paste the method below to see what it returns:
    public string GetCanonicalPath(string path)
    Then you can supply those generated paths to the sftp command line utility to see which error message it generates, this should help to diagnose what exactly is going wrong there. If a call to GetCanonicalPath misspells the absolute path of a file somehow, then worth constructing the path in your code manually. There is also a chance that we are getting the Failure error code due to different reasons, seen somewhere on SO written that this code can be caused by Not enough space SFTP error etc.

  6. squarewave24 commented on Aug 25, 2020

    @squarewave24

    i am also getting this error. verified that paths are ok.
    the issue must be with connection because i am hitting 2 identical servers (identical in content, from the same 3rd party provider) but only 1 of them works. the other throws this vague error, and i stepped through the code 20x. somehow response status comes back as "Failure" and empty exception is re-thrown. but i can't see what/where the Failure is set.

    #720

  7. Imbaker1234 commented on Jan 14, 2023

    @Imbaker1234

    Problem

    Encountered this error when attempting to call ReadAllFiles during my work on the CES.SquareDUpdater.

    I was able to list all of the files, indicating this was not a lack of access, but some implementation detail.


    Discovery - 1

    I was reading all items in the directory, not just files. Calling ReadAllText on directories causes this very generic failure displayed here.


    Solution

    After listing all items (files and directories) in my target/parent directory I was searching I filtered out directories.

            public async Task<IEnumerable<string>> ListFiles(string remoteDirectory)
            {
                return await ConnectAndOperate(() => Task.FromResult(_client.ListDirectory(remoteDirectory)
                        .Where(item => !item.IsDirectory) // This is where I made the change.
                        .OrderBy(file => file.LastWriteTimeUtc)
                        .Select(file => file.FullName)),
                    $"Listing files in `{remoteDirectory}");
            }

    #DevLog

  8. stasberkov commented on Jun 4, 2026

    @stasberkov

    I get this "Renci.SshNet.Common.SshException: Failure" exception when try to rename a file into file with already existing name. Instead of something like "FileAlreadyExists" exception I get generic "Failure" error message. SSHNET guys, please add specific error messages.

  9. Rob-Hague commented on Oct 19, 2026

    @Rob-Hague
    Collaborator

    I think this is a big mix of issues that isn't going to help anyone. For the "Failure" error, this is a catch-all error type in the SFTP spec that is returned by the server, not an error from the library and the library can't really do anything about it. #1716 / 2025.1.0 provides some improvement, largely to the extent that is possible.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions