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.
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.
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 yourSFTPTOGO_URLis correct:sftp://username:password@host - Port access
SFTP uses port22by 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 usingStrictHostKeyChecking=noin 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 shouldSFTPTOGO_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.
SFTP uses port 22 by default because it runs over SSH.
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.
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.