web
You’re offline. This is a read only version of the page.
close
Skip to main content

Announcements

No record found.

News and Announcements icon
Community site session details

Community site session details

Session Id :
Finance | Project Operations, Human Resources, ...
Answered

Cannot access a disposed object. Object name: 'Renci.SshNet.SftpClient', While connecting SFTP.

(3) ShareShare
ReportReport
Posted on by 331
Hi,
 
I'm working on a scenario in D365 F&O where I need to connect to an SFTP server to send and read files. The SFTP server requires authentication using a username and private key (no password).
To achieve this, I created a C# class library that uses Renci.SshNet to establish the SFTP connection. I then call this C# code from X++. The connection returns success, which means the authentication is working.

However, when I try to access the SftpClient instance from X++ -- for example, to check if the connection is still active or to perform operations like file listing -- I encounter the below error:
Cannot access a disposed object. Object name: 'Renci.SshNet.SftpClient'.
 
Has anyone encountered this issue before? Is there a recommended pattern for handling SftpClient in a way that it works reliably with X++?
Any help or examples would be greatly appreciated.
 
My X++ code:
using SFTPConnection;
using Renci.SshNet;
using Renci.SshNet.Sftp;
using Renci.SshNet.SftpClient;

public class ConnectSFTPServer
{
    public static void main(Args args)
    {
        System.Exception ex;
        //Renci.SshNet.SftpClient sftpClient;
        SftpClient sftpClient;
        System.IO.Stream  stream;
        str connectionStatus;

        try
        {
            System.IO.Stream publicKeyStream;
            
            //I get my private key's stream here
            sftpClient = SFTPConnection.SFTPConnectionAndUploadFile::ConnectSFTP('000.000.000.00', 22, 'XYZXYZ', 'XYZXYZ', publicKeyStream, 'XYZXYZ');

            if(sftpClient != null)
            {
                ttsBegin;
                
                if (sftpClient.IsConnected) //I got error in this line
                    connectionStatus += 'Connected';
                else
                {
                    sftpClient.Connect();
                }
                sftpClient.Disconnect();
                sftpClient.Dispose();
                ttscommit;
            }
            Info(connectionStatus);
        }
        catch(ex)
        {
            System.String messageEx = ex.Message;
            info(strFmt("%1 - %2", connectionStatus, messageEx));
        }
    }
}
 
 
My C# code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Renci.SshNet;
using Renci.SshNet.Sftp;
using System.IO;
using System.Net;
using System.Linq;
using System.Runtime.CompilerServices;

namespace SFTPConnection
{
    public class SFTPConnectionAndUploadFile
    {
        public static SftpClient ConnectSFTP(string host, int port, string username, string password, Stream privateKeyFileStream, string passphrase)
        {
            List<AuthenticationMethod> methods;
            SftpClient sftpClient = (SftpClient)null;

            if (privateKeyFileStream != null)
            {
                PrivateKeyFile privateKeyFile = new PrivateKeyFile(privateKeyFileStream, passphrase);
                methods = new List<AuthenticationMethod>
                {
                    new PrivateKeyAuthenticationMethod(username, privateKeyFile)
                };
            }
            else
            {
                methods = new List<AuthenticationMethod>
                {
                    new PasswordAuthenticationMethod(username, password)
                };
            }
            try
            {
                var connectionInfo = new ConnectionInfo(host, port, username, methods.ToArray());
                using (sftpClient = new SftpClient(connectionInfo))
                {
                    sftpClient.Connect();
                    if (!sftpClient.IsConnected)
                    {
                        sftpClient = null;
                    }
                }
                return sftpClient;
            }

            catch (Exception ex)
            {
                ((BaseClient)sftpClient)?.Dispose();
                return (SftpClient)null;
            }
        }
    }
}
Note: If I call the C# method from X++, I got "Success" message only.
C# Code:
public static string SFTPConnect(string host, int port, string username, string password, Stream privateKeyFileStream, string passphrase)
        {
            List<AuthenticationMethod> methods;
            string successStr;

            if (privateKeyFileStream != null)
            {
                PrivateKeyFile privateKeyFile = new PrivateKeyFile(privateKeyFileStream, passphrase);
                methods = new List<AuthenticationMethod>
                {
                    new PrivateKeyAuthenticationMethod(username, privateKeyFile)
                };
            }
            else
            {
                methods = new List<AuthenticationMethod>
                {
                    new PasswordAuthenticationMethod(username, password)
                };
}
            try
            {
                var connectionInfo = new ConnectionInfo(host, port, username, methods.ToArray());
                using (SftpClient sftpclient = new SftpClient(connectionInfo))
                {
                    sftpclient.Connect();
                    if (sftpclient.IsConnected)
                        successStr = "Connected";
                    else
                        successStr = "Not Connected";

                    sftpclient.Disconnect();
                    sftpclient.Dispose();
                }
            }

            catch (Exception ex)
            {
                successStr = "Fail";
            }
            return successStr;
        }
 
Categories:
I have the same question (1)
  • Verified answer
    Martin Dráb Profile Picture
    239,040 Most Valuable Professional on at
    The reason lies in your C#. You close the client before returning it, therefore what you get in X++ is a client that can't be used anymore. Remove the using block from C# and handle the closing in X++. You have already have X++ code attempting to do so, but it's not correct, because it doesn't dispose the client if an exception gets thrown. Utilize either a using block or a finally block.

Under review

Thank you for your reply! To ensure a great experience for everyone, your content is awaiting approval by our Community Managers. Please check back later.

Helpful resources

Quick Links

Introducing the 2026 Season 1 community Super Users

Congratulations to our 2026 Super Stars!

Meet the Microsoft Dynamics 365 Contact Center Champions

We are thrilled to have these Champions in our Community!

Congratulations to the March Top 10 Community Leaders

These are the community rock stars!

Leaderboard > Finance | Project Operations, Human Resources, AX, GP, SL

#1
Giorgio Bonacorsi Profile Picture

Giorgio Bonacorsi 616

#2
André Arnaud de Calavon Profile Picture

André Arnaud de Cal... 460 Super User 2026 Season 1

#3
Syed Haris Shah Profile Picture

Syed Haris Shah 331 Super User 2026 Season 1

Last 30 days Overall leaderboard

Product updates

Dynamics 365 release plans