Skip to content

Spring SFTP : Unable to rename .writing file

I am using Spring SFTP integration to transfer the file and many time I got this error. It seems two threads are trying to transfer same file and conflict with each other

2020-08-03 08:31:55,766 INF [task-scheduler-8 ] o.s.i.ftp.session.FtpSession – File has been successfully transferred from: ./abc.ext.200803
2020-08-03 08:31:55,849 INF [task-scheduler-7 ] o.s.i.ftp.session.FtpSession – File has been successfully transferred from: ./abc.ext.200803
2020-08-03 08:31:55,850 INF [task-scheduler-7 ] .s.i.f.i.FtpInboundFileSynchronizer – Cannot rename ‘/local/download/abc.ext.200803.writing’ to local file ‘/local/download/abc.ext.200803’ after deleting. The local file may be busy in some other process.

Is there a way so both threads should not interfere with each other?

I am using following code –

public SftpInboundFileSynchronizer ftpInboundFileSynchronizer() {
    SftpInboundFileSynchronizer fileSynchronizer = new SftpInboundFileSynchronizer(sftpSessionFactory());


    fileSynchronizer.setFilter(new SFTPLastModifiedFileFilter(remoteFileFilter));
    return fileSynchronizer;

private boolean isFTPSessionOK() {
    try {
        SessionFactory<LsEntry> ftpSessionFactory = sftpSessionFactory();
        boolean open = ftpSessionFactory.getSession().isOpen();"FTPSession is good ? " + open);
        return open;
    } catch (Exception e) {
        LOG.error("FTPSession is not good because of error : " + e);
    return false;

public SessionFactory<LsEntry> sftpSessionFactory() {
    DefaultSftpSessionFactory sf = new DefaultSftpSessionFactory();
    return new CachingSessionFactory<LsEntry>(sf);

@InboundChannelAdapter(channel = "sftpChannel", poller = @Poller(fixedDelay = "${${}.ftp.poller.delay:600000}", maxMessagesPerPoll = "1"))
public MessageSource<File> ftpMessageSource() {
    SftpInboundFileSynchronizingMessageSource source = new SftpInboundFileSynchronizingMessageSource(ftpInboundFileSynchronizer());
    source.setLocalDirectory(new File(localFtpDirectory));
    return source;

@ServiceActivator(inputChannel = "sftpChannel")
public MessageHandler ftpHandler() {
    return new MessageHandler() {

        public void handleMessage(Message<?> message) throws MessagingException {
  "File '{}' is ready for reading after SFTP", message.getPayload());


You have only this for filtering:

fileSynchronizer.setFilter(new SFTPLastModifiedFileFilter(remoteFileFilter));

but what about a filter which is going to prevent duplicates on subsequent poll?

See AcceptOnceFileListFilter. And together with that SFTPLastModifiedFileFilter you should use a ChainFileListFilter.

See docs for more info: