Search code examples
javaspring-bootspring-integrationsftpjsch

In JSch, what does 'invalid handle' mean?


I am using JSch with Spring Integration to store files from our Spring Boot app to an SFTP server. Recently, the uploads started to fail with the following error:

Caused by: org.springframework.messaging.MessagingException: Failed to write to './user/2023-04-05_04:00:00_TEST_FILE_FOR_UPLOAD_TO_SFTP_PRODLIKE.csv' while uploading the file; nested exception is org.springframework.core.NestedIOException: failed to write file; nested exception is 9: Invalid handle.
    at org.springframework.integration.file.remote.RemoteFileTemplate.sendFileToRemoteDirectory(RemoteFileTemplate.java:573) ~[spring-integration-file-5.5.12.jar!/:5.5.12]
    at org.springframework.integration.file.remote.RemoteFileTemplate.doSend(RemoteFileTemplate.java:353) ~[spring-integration-file-5.5.12.jar!/:5.5.12]
    ... 166 common frames omitted
 Caused by: org.springframework.core.NestedIOException: failed to write file; nested exception is 9: Invalid handle.
    at org.springframework.integration.sftp.session.SftpSession.write(SftpSession.java:177) ~[spring-integration-sftp-5.5.8.jar!/:5.5.8]
    at org.springframework.integration.file.remote.RemoteFileTemplate.doSend(RemoteFileTemplate.java:582) ~[spring-integration-file-5.5.12.jar!/:5.5.12]
    at org.springframework.integration.file.remote.RemoteFileTemplate.sendFileToRemoteDirectory(RemoteFileTemplate.java:570) ~[spring-integration-file-5.5.12.jar!/:5.5.12]
    ... 167 common frames omitted
 Caused by: com.jcraft.jsch.SftpException: Invalid handle.
    at com.jcraft.jsch.ChannelSftp.throwStatusError(ChannelSftp.java:2873) ~[jsch-0.1.55.jar!/:na]
    at com.jcraft.jsch.ChannelSftp._put(ChannelSftp.java:594) ~[jsch-0.1.55.jar!/:na]
    at com.jcraft.jsch.ChannelSftp.put(ChannelSftp.java:540) ~[jsch-0.1.55.jar!/:na]
    at com.jcraft.jsch.ChannelSftp.put(ChannelSftp.java:492) ~[jsch-0.1.55.jar!/:na]
    at org.springframework.integration.sftp.session.SftpSession.write(SftpSession.java:174) ~[spring-integration-sftp-5.5.8.jar!/:5.5.8]
    ... 169 common frames omitted

Shockingly, I can find nothing about this specific error when I am Googling. I see some somewhat similar results, but generally not about JSch or about a different JSch error.

Most of the somewhat similar search results seem to hint at a problem with the path, but I cannot see anything different or strange with the path to which we are trying to write.

I have turned on trace logging and it shows that we are connecting/authenticating successfully (it seems to be when it tries to write the file that it fails). I have checked for low disk space and I have tested witch changing the file name and the write directory.

What specifically does 'handle' mean in this context and what are the rules for its validity?

Our SFTP Impl:

public class SftpService {
    
    private SftpMessagingGateway gateway;

    @Autowired
    public SftpService(SftpMessagingGateway gateway) {
        this.gateway = gateway;
    }

    public boolean writeStreamToFtp(InputStream data, String filename, String path) {
        if (gateway == null) throw new IllegalStateException("SFTP Gateway is not initialized");

        Message<InputStream> mess = MessageBuilder.withPayload(data)
        .setHeader(FileHeaders.FILENAME, filename)
        .setHeader("path", path)
        .build();
        
        try {
            gateway.send(mess);
            log.info("successful persistence of report to sftp server");
            return true;
        } catch (Exception e) {
            log.error("failed to persist report to sftp server", e);
            return false;
        }
    }

}

Solution

  • Thanks to j_b and his comment for stating the obvious next step and putting me back on track: "check the sftp server log to see if there is any more useful debugging information".

    I requested the sftp logs and found this:

    CreateFile() failed!, Error=123, "The filename, directory name, or volume label syntax is incorrect."
    

    Not super helpful, but it did confirm it was indeed a path issue which my research suggested it might be. I took a harder look at the filename I was trying to write:

    2023-04-05_04:00:00_TEST_FILE_FOR_UPLOAD_TO_SFTP_PRODLIKE.csv

    ... and I (finally) noticed the colons. Colon is not valid in filenames. Removing them resolved the issue.

    So in short, 'Invalid handle' seems to mean that Jsch failed to write to the file. Check your SFTP logs for more info. It is often a path or filename-related issue.