How to connect to SFTP in Java: Upload, Download, List Files

This guide shows how to connect to an SFTP server in Java using JSch.

You’ll establish a connection, list remote files, upload and download data, and close the session cleanly. The example uses a single connection string stored in SFTPTOGO_URL, which contains your host, username, and password in a standard URI format.


Requirements for Java SFTP setup

There are several Java libraries available for working with SFTP. This guide uses the maintained JSch implementation (mwiede/jsch), which supports modern SSH algorithms and active OpenSSH compatibility.

💡
Note: The maintained mwiede/jsch library still uses the com.jcraft.jsch package name for compatibility.

Add the dependency to your project:

Using Maven:

<dependency>
    <groupId>com.github.mwiede</groupId>
    <artifactId>jsch</artifactId>
    <version>0.2.16</version>
</dependency>

Using Gradle:

implementation 'com.github.mwiede:jsch:0.2.16'

Connecting to SFTP in Java

This example uses an environment variable named SFTPTOGO_URL to store connection details in URI format:

sftp://username:password@host

This value contains the host, username, and password in a single URI format, which should be parsed into separate values before establishing the connection.

The connection is established using JSch by opening an SSH session and then creating an SFTP channel.

💡
Note: This example disables strict host key checking for simplicity. In production, you should configure known hosts using jsch.setKnownHosts(...) and avoid setting StrictHostKeyChecking to "no".
package com.sftptogo;

import com.jcraft.jsch.*;
import com.sftptogo.util.Util;

import java.util.Properties;
import java.util.Vector;

/**
 * A simple SFTP client using JSCH (mwiede/jsch maintained version)
 */
public final class SftpClient {
    private final String      host;
    private final int         port;
    private final String      username;
    private final JSch        jsch;
    private       ChannelSftp channel;
    private       Session     session;

    /**
     * @param host     remote host
     * @param port     remote port
     * @param username remote username
     */
    public SftpClient(String host, int port, String username) {
        this.host     = host;
        this.port     = port;
        this.username = username;
        jsch          = new JSch();
    }

    /**
     * Use default port 22
     *
     * @param host     remote host
     * @param username username on host
     */
    public SftpClient(String host, String username) {
        this(host, 22, username);
    }

    /**
     * Authenticate with remote using password
     *
     * @param password password of remote
     * @throws JSchException If there is problem with credentials or connection
     */
    public void authPassword(String password) throws JSchException {
        session = jsch.getSession(username, host, port);
        //disable known hosts checking
        //if you want to set known hosts file you can set with jsch.setKnownHosts("path to known hosts file");
        var config = new Properties();
        config.put("StrictHostKeyChecking", "no");
        session.setConfig(config);
        session.setPassword(password);
        session.connect();
        channel = (ChannelSftp) session.openChannel("sftp");
        channel.connect();
    }


    public void authKey(String keyPath, String pass) throws JSchException {
        jsch.addIdentity(keyPath, pass);
        session = jsch.getSession(username, host, port);
        //disable known hosts checking
        //if you want to set knows hosts file You can set with jsch.setKnownHosts("path to known hosts file");
        var config = new Properties();
        config.put("StrictHostKeyChecking", "no");
        session.setConfig(config);
        session.connect();
        channel = (ChannelSftp) session.openChannel("sftp");
        channel.connect();
    }
}

Listing Files over SFTP in Java

Now that we have a working connection, we can use it to list files on the remote SFTP server. Our wrapper function listFiles calls the channel’s ls function to retrieve the list of remote files, iterate over them and print each file’s permissions, name, and size.

/**
 * List all files including directories
 *
 * @param remoteDir Directory on remote from which files will be listed
 * @throws SftpException If there is any problem with listing files related to permissions etc
 * @throws JSchException If there is any problem with connection
 */
@SuppressWarnings("unchecked")
public void listFiles(String remoteDir) throws SftpException, JSchException {
    if (channel == null) {
        throw new IllegalArgumentException("Connection is not available");
    }
    System.out.printf("Listing [%s]...%n", remoteDir);
    channel.cd(remoteDir);
    Vector<ChannelSftp.LsEntry> files = channel.ls(".");
    for (ChannelSftp.LsEntry file : files) {
        var name        = file.getFilename();
        var attrs       = file.getAttrs();
        var permissions = attrs.getPermissionsString();
        var size        = Util.humanReadableByteCount(attrs.getSize());
        if (attrs.isDir()) {
            size = "PRE";
        }
        System.out.printf("[%s] %s(%s)%n", permissions, name, size);
    }
}

Uploading Files over SFTP in Java

The next step is to upload a file. Our class’s uploadFile takes two arguments: localPath (the file to upload) and remotePath (where to upload it to on the server). An example call would look like this: client.uploadFile("./local.txt", "/remote.txt");

/**
 * Upload a file to remote
 *
 * @param localPath  full path of local file
 * @param remotePath full path of remote file
 * @throws JSchException If there is any problem with connection
 * @throws SftpException If there is any problem with uploading file permissions etc
 */
public void uploadFile(String localPath, String remotePath) throws JSchException, SftpException {
    System.out.printf("Uploading [%s] to [%s]...%n", localPath, remotePath);
    if (channel == null) {
        throw new IllegalArgumentException("Connection is not available");
    }
    channel.put(localPath, remotePath);
}

Downloading Files over SFTP in Java

The final step is downloading files from the SFTP server. The downloadFile function also takes two arguments: remotePath (file to download) and localPath (where to download the file to). You would call the function like so: client.downloadFile("/remote.txt", "./download.txt");

/**
 * Download a file from remote
 *
 * @param remotePath full path of remote file
 * @param localPath  full path of where to save file locally
 * @throws SftpException If there is any problem with downloading file related permissions etc
 */
public void downloadFile(String remotePath, String localPath) throws SftpException {
    System.out.printf("Downloading [%s] to [%s]...%n", remotePath, localPath);
    if (channel == null) {
        throw new IllegalArgumentException("Connection is not available");
    }
    channel.get(remotePath, localPath);
}

Troubleshooting Java SFTP connections

If your Java SFTP connection fails, these are the most common causes to check before changing your code.

  • Connection details
    Make sure your SFTPTOGO_URL is correct:
    sftp://username:password@host
  • Port access
    SFTP uses port 22 by default because it runs over SSH. Ensure outbound access is allowed.
  • Authentication errors
    “Permission denied” usually means incorrect credentials or wrong authentication method.
  • Host key verification
    Avoid using StrictHostKeyChecking=no in production. Configure known hosts instead.
  • File paths
    Ensure remote paths are valid relative to the SFTP user’s home directory.
  • Session errors
    “Connection is not available” usually means authentication or session setup failed.

The whole Java SFTP example

All done! If you would like to run the entire program from start to finish, follow the instructions on how to build and run the project here

package com.sftptogo;

import com.jcraft.jsch.*;
import com.sftptogo.util.Util;

import java.util.Properties;
import java.util.Vector;

/**
 * A simple SFTP client using JSCH (mwiede/jsch maintained version)
 */
public final class SftpClient {
    private final String      host;
    private final int         port;
    private final String      username;
    private final JSch        jsch;
    private       ChannelSftp channel;
    private       Session     session;

    /**
     * @param host     remote host
     * @param port     remote port
     * @param username remote username
     */
    public SftpClient(String host, int port, String username) {
        this.host     = host;
        this.port     = port;
        this.username = username;
        jsch          = new JSch();
    }

    /**
     * Use default port 22
     *
     * @param host     remote host
     * @param username username on host
     */
    public SftpClient(String host, String username) {
        this(host, 22, username);
    }

    /**
     * Authenticate with remote using password
     *
     * @param password password of remote
     * @throws JSchException If there is problem with credentials or connection
     */
   //if you want to set known hosts file you can use jsch.setKnownHosts("path to known hosts file");
        session = jsch.getSession(username, host, port);
        //disable known hosts checking
        //if you want to set known hosts file You can set with jsch.setKnownHosts("path to known hosts file");
        var config = new Properties();
        config.put("StrictHostKeyChecking", "no");
        session.setConfig(config);
        session.setPassword(password);
        session.connect();
        channel = (ChannelSftp) session.openChannel("sftp");
        channel.connect();
    }


    //if you want to set known hosts file you can use jsch.setKnownHosts("path to known hosts file");
        jsch.addIdentity(keyPath, pass);
        session = jsch.getSession(username, host, port);
        //disable known hosts checking
        //if you want to set known hosts file You can set with jsch.setKnownHosts("path to known hosts file");
        var config = new Properties();
        config.put("StrictHostKeyChecking", "no");
        session.setConfig(config);
        session.connect();
        channel = (ChannelSftp) session.openChannel("sftp");
        channel.connect();
    }

    /**
     * List all files including directories
     *
     * @param remoteDir Directory on remote from which files will be listed
     * @throws SftpException If there is any problem with listing files related to permissions etc
     * @throws JSchException If there is any problem with connection
     */
    @SuppressWarnings("unchecked")
    public void listFiles(String remoteDir) throws SftpException, JSchException {
        if (channel == null) {
            throw new IllegalArgumentException("Connection is not available");
        }
        System.out.printf("Listing [%s]...%n", remoteDir);
        channel.cd(remoteDir);
        Vector<ChannelSftp.LsEntry> files = channel.ls(".");
        for (ChannelSftp.LsEntry file : files) {
            var name        = file.getFilename();
            var attrs       = file.getAttrs();
            var permissions = attrs.getPermissionsString();
            var size        = Util.humanReadableByteCount(attrs.getSize());
            if (attrs.isDir()) {
                size = "PRE";
            }
            System.out.printf("[%s] %s(%s)%n", permissions, name, size);
        }
    }

    /**
     * Upload a file to remote
     *
     * @param localPath  full path of location file
     * @param remotePath full path of remote file
     * @throws JSchException If there is any problem with connection
     * @throws SftpException If there is any problem with uploading file permissions etc
     */
    public void uploadFile(String localPath, String remotePath) throws JSchException, SftpException {
        System.out.printf("Uploading [%s] to [%s]...%n", localPath, remotePath);
        if (channel == null) {
            throw new IllegalArgumentException("Connection is not available");
        }
        channel.put(localPath, remotePath);
    }

    /**
     * Download a file from remote
     *
     * @param remotePath full path of remote file
     * @param localPath  full path of where to save file locally
     * @throws SftpException If there is any problem with downloading file related permissions etc
     */
    public void downloadFile(String remotePath, String localPath) throws SftpException {
        System.out.printf("Downloading [%s] to [%s]...%n", remotePath, localPath);
        if (channel == null) {
            throw new IllegalArgumentException("Connection is not available");
        }
        channel.get(remotePath, localPath);
    }

    /**
     * Delete a file on remote
     *
     * @param remoteFile full path of remote file
     * @throws SftpException If there is any problem with deleting file related to permissions etc
     */
    public void delete(String remoteFile) throws SftpException {
        System.out.printf("Deleting [%s]...%n", remoteFile);
        if (channel == null) {
            throw new IllegalArgumentException("Connection is not available");
        }
        channel.rm(remoteFile);
    }

    /**
     * Disconnect from remote
     */
    public void close() {
        if (channel != null) {
            channel.exit();
        }
        if (session != null && session.isConnected()) {
            session.disconnect();
        }
    }
}

In conclusion

Congratulations on connecting to SFTP using Java!

You now have a working Java SFTP client using JSch, capable of connecting, listing files, and transferring data. For production use, focus on secure authentication, host verification, and reliable session handling.

Check out more code samples on Github. Explore SFTP automation to reduce human error and streamline workflows.


Frequently asked questions

How do I connect to an SFTP server in Java?

Use JSch to create an SSH session, authenticate with a password or key, and open an SFTP channel to interact with remote files.

What is JSch in Java?

JSch is a Java library that implements SSH2, which means it can be used for SFTP file transfer, SSH sessions, and related secure connection tasks.

What should SFTPTOGO_URL look like?

SFTPTOGO_URL should use this format: sftp://username:password@host. It stores the host, username, and password in a single connection string.

What port does SFTP use?

SFTP uses port 22 by default because it runs over SSH.

Why is my Java SFTP connection failing?

Common causes include incorrect credentials, blocked outbound access on port 22, invalid remote file paths, or session setup problems before the SFTP channel is opened.

Should I disable StrictHostKeyChecking in JSch?

No. Disabling StrictHostKeyChecking may be acceptable for quick testing, but in production you should configure known hosts and verify the server identity properly.