Hi Camel team, I'm currently looking into a production issue we're having that has led to data loss. I've tried searching for solutions but to no avail. In short, what we're experiencing is that a Camel route downloads several files from a FTPS server and saves them to a local file path. Some files are fine, some files have had their content replaced by the content of another file.
As an example, 3 files: Test1.xml, Test2.xml, Test3.xml. The content of file Test3.xml has been replaced by the content of file Test1.xml. Test1.xml and Test2.xml are unaffected. In my world this is a "should never be able to happen"-error. The issue doesn't happen every day and I can see in our logs that the retrieve file operations have failed on days with error in files. We're getting read time out and cannot retrieve file exceptions, possible because the supplier is currently writing to the file or having a file lock, I don't know. My assumption is that the route will re-try to fetch the file and somehow the active context filename of one filename is transferred into another context (not sure of the inner workings) of another file leading to using an incorrect filename. I don't have any idea how this can happen. We didn't use the fileExist option when writing the files because we know the file supplier uses unique filenames but I made an immediate hotfix adding fileExist=Move to the route so we'll at least have a backup. Any help with this issue will be appreciated. Further details: New application that has been running for two weeks before first issue. We've had the issue on 4 separate occasions. We've been using older Camel versions for almost a decade that has a similar route with no issues. Camel 3.8.0 Spring Boot 2.4.2 Windows Server 2016, Java 8 (AdoptOpenJDK jdk-8.0.282.8) The route, using Java DSL: Sort the files on the FTPS server, download each file, save file in an archive folder by date and then in a different folder for further handling. from(uri) .routeId("consume-ftp") .setHeader("direction", simple("inbound")) .log(LoggingLevel.DEBUG, "route.ftp-download", "Retrieving file from FTP: ${file:name}") .toD(file:// + configuration.getArchiveInbound() + "/${date:now:yyyy-MM-dd}?flatten=true") .to(file:// + configuration.getInbound() + "?flatten=true") .log(LoggingLevel.INFO, "route.ftp-download", "Inbound file archived and sent to handling: ${file:name}"); where, String uri = "ftps://example.com:1234/download?username=user&password=pw" + "&ftpClient.keyStore.file=filepath" + "&ftpClient.keyStore.password=pw" + "&ftpClient.keyStore.keyPassword=pw" + "&delete=true" + "&include=.*\\.xml\\Z" + "&passiveMode=true" + "&binary=true" + "&stepwise=false" + "&autoCreate=false" + "&disconnect=true" + "&maxMessagesPerPoll=100" + "&maximumReconnectAttempts=3" + "&reconnectDelay=600000" + "&scheduler=quartz" + "&scheduler.cron=0 0/30 * * * ?" + "&localWorkDirectory=localpath" + "&preSort=true" + "&sorter=#fileSorter"; I don't know why maximumReconnectAttempts and reconnectDelay were added and they might be related to the issue since they could keep a filename in memory. I have now removed those two and added fileExist and moveExisting to the two producers to avoid losing data. Logs: The handling of the below logs has led to: The content of Test11.xml has been replaced by Test6.xml The content of Test13.xml has been replaced by Test11.xml The content of Test14.xml has been replaced by Test12.xml I did a bit of cleanup to avoid too much repetition: 2021-06-17 01:30:00,015 [DEBUG] (DefaultQuartzScheduler-camel-1_Worker-1) [org.apache.camel.component.file.remote.RemoteFileConsumer.connectIfNecessary]: Exception checking connection status: File operation failed: null Connection is not open. Code: 221 2021-06-17 01:30:00,015 [DEBUG] (DefaultQuartzScheduler-camel-1_Worker-1) [org.apache.camel.component.file.remote.RemoteFileConsumer.connectIfNecessary]: Not connected/logged in, connecting to: ftps://u...@example.com:1234 2021-06-17 01:30:09,312 [DEBUG] (DefaultQuartzScheduler-camel-1_Worker-1) [org.apache.camel.component.file.remote.RemoteFileConsumer.connectIfNecessary]: Connected and logged in to: ftps://u...@example.com:1234 2021-06-17 01:30:09,577 [WARN ] (DefaultQuartzScheduler-camel-1_Worker-1) [org.apache.camel.component.file.remote.FtpConsumer.log]: Error processing file RemoteFile[Test1.xml] due to File operation failed: 150 File status okay; about to open data connection. Couldn't kickstart handshaking. Code: 150. Caused by: [org.apache.camel.component.file.GenericFileOperationFailedException - File operation failed: 150 File status okay; about to open data connection. Couldn't kickstart handshaking. Code: 150] org.apache.camel.component.file.GenericFileOperationFailedException: File operation failed: 150 File status okay; about to open data connection. Couldn't kickstart handshaking. Code: 150 at org.apache.camel.component.file.remote.FtpOperations.retrieveFileToFileInLocalWorkDirectory(FtpOperations.java:629) at org.apache.camel.component.file.remote.FtpOperations.retrieveFile(FtpOperations.java:416) at org.apache.camel.component.file.GenericFileConsumer.processExchange(GenericFileConsumer.java:435) at org.apache.camel.component.file.remote.RemoteFileConsumer.processExchange(RemoteFileConsumer.java:147) at org.apache.camel.component.file.GenericFileConsumer.processBatch(GenericFileConsumer.java:240) at org.apache.camel.component.file.GenericFileConsumer.poll(GenericFileConsumer.java:201) at org.apache.camel.support.ScheduledPollConsumer.doRun(ScheduledPollConsumer.java:190) at org.apache.camel.support.ScheduledPollConsumer.run(ScheduledPollConsumer.java:107) at org.apache.camel.pollconsumer.quartz.QuartzScheduledPollConsumerJob.execute(QuartzScheduledPollConsumerJob.java:61) at org.quartz.core.JobRunShell.run(JobRunShell.java:202) at org.quartz.simpl.SimpleThreadPool$WorkerThread.run(SimpleThreadPool.java:573) Caused by: javax.net.ssl.SSLException: Couldn't kickstart handshaking at sun.security.ssl.Alert.createSSLException(Alert.java:127) at sun.security.ssl.TransportContext.fatal(TransportContext.java:324) at sun.security.ssl.TransportContext.fatal(TransportContext.java:267) at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:397) at org.apache.commons.net.ftp.FTPSClient._openDataConnection_(FTPSClient.java:641) at org.apache.commons.net.ftp.FTPClient._retrieveFile(FTPClient.java:1896) at org.apache.commons.net.ftp.FTPClient.retrieveFile(FTPClient.java:1882) at org.apache.camel.component.file.remote.FtpOperations.retrieveFileToFileInLocalWorkDirectory(FtpOperations.java:602) ... 10 common frames omitted Suppressed: java.net.SocketException: Connection reset by peer: socket write error at java.net.SocketOutputStream.socketWrite0(Native Method) at java.net.SocketOutputStream.socketWrite(SocketOutputStream.java:111) at java.net.SocketOutputStream.write(SocketOutputStream.java:155) at sun.security.ssl.SSLSocketOutputRecord.encodeAlert(SSLSocketOutputRecord.java:81) at sun.security.ssl.TransportContext.fatal(TransportContext.java:355) ... 16 common frames omitted Caused by: java.net.SocketException: Connection reset by peer: socket write error at java.net.SocketOutputStream.socketWrite0(Native Method) at java.net.SocketOutputStream.socketWrite(SocketOutputStream.java:111) at java.net.SocketOutputStream.write(SocketOutputStream.java:155) at sun.security.ssl.SSLSocketOutputRecord.flush(SSLSocketOutputRecord.java:251) at sun.security.ssl.HandshakeOutStream.flush(HandshakeOutStream.java:89) at sun.security.ssl.ClientHello$ClientHelloKickstartProducer.produce(ClientHello.java:580) at sun.security.ssl.SSLHandshake.kickstart(SSLHandshake.java:500) at sun.security.ssl.ClientHandshakeContext.kickstart(ClientHandshakeContext.java:107) at sun.security.ssl.TransportContext.kickstart(TransportContext.java:231) at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:387) ... 14 common frames omitted 2021-06-17 01:35:09,577 [WARN ] (DefaultQuartzScheduler-camel-1_Worker-1) [org.apache.camel.component.file.remote.FtpConsumer.log]: Error processing file RemoteFile[Test2.xml] due to File operation failed: Read timed out. Code: 150. org.apache.camel.component.file.GenericFileOperationFailedException: File operation failed: Read timed out. Code: 150 at org.apache.camel.component.file.remote.FtpOperations.retrieveFileToFileInLocalWorkDirectory(FtpOperations.java:629) at org.apache.camel.component.file.remote.FtpOperations.retrieveFile(FtpOperations.java:416) at org.apache.camel.component.file.GenericFileConsumer.processExchange(GenericFileConsumer.java:435) at org.apache.camel.component.file.remote.RemoteFileConsumer.processExchange(RemoteFileConsumer.java:147) at org.apache.camel.component.file.GenericFileConsumer.processBatch(GenericFileConsumer.java:240) at org.apache.camel.component.file.GenericFileConsumer.poll(GenericFileConsumer.java:201) at org.apache.camel.support.ScheduledPollConsumer.doRun(ScheduledPollConsumer.java:190) at org.apache.camel.support.ScheduledPollConsumer.run(ScheduledPollConsumer.java:107) at org.apache.camel.pollconsumer.quartz.QuartzScheduledPollConsumerJob.execute(QuartzScheduledPollConsumerJob.java:61) at org.quartz.core.JobRunShell.run(JobRunShell.java:202) at org.quartz.simpl.SimpleThreadPool$WorkerThread.run(SimpleThreadPool.java:573) Caused by: java.net.SocketTimeoutException: Read timed out at java.net.SocketInputStream.socketRead0(Native Method) at java.net.SocketInputStream.socketRead(SocketInputStream.java:116) at java.net.SocketInputStream.read(SocketInputStream.java:171) at java.net.SocketInputStream.read(SocketInputStream.java:141) at sun.security.ssl.SSLSocketInputRecord.read(SSLSocketInputRecord.java:457) at sun.security.ssl.SSLSocketInputRecord.bytesInCompletePacket(SSLSocketInputRecord.java:68) at sun.security.ssl.SSLSocketImpl.readApplicationRecord(SSLSocketImpl.java:1095) at sun.security.ssl.SSLSocketImpl.access$200(SSLSocketImpl.java:72) at sun.security.ssl.SSLSocketImpl$AppInputStream.read(SSLSocketImpl.java:815) at sun.nio.cs.StreamDecoder.readBytes(StreamDecoder.java:284) at sun.nio.cs.StreamDecoder.implRead(StreamDecoder.java:326) at sun.nio.cs.StreamDecoder.read(StreamDecoder.java:178) at java.io.InputStreamReader.read(InputStreamReader.java:184) at java.io.BufferedReader.fill(BufferedReader.java:161) at java.io.BufferedReader.readLine(BufferedReader.java:324) at java.io.BufferedReader.readLine(BufferedReader.java:389) at org.apache.commons.net.ftp.FTP.__getReply(ftp://FTP.java:320) at org.apache.commons.net.ftp.FTP.__getReply(ftp://FTP.java:299) at org.apache.commons.net.ftp.FTP.sendCommand(ftp://FTP.java:522) at org.apache.commons.net.ftp.FTPSClient.sendCommand(FTPSClient.java:563) at org.apache.commons.net.ftp.FTP.sendCommand(ftp://FTP.java:644) at org.apache.commons.net.ftp.FTP.sendCommand(ftp://FTP.java:618) at org.apache.commons.net.ftp.FTP.pasv(ftp://FTP.java:1041) at org.apache.commons.net.ftp.FTPClient._openDataConnection_(FTPClient.java:896) at org.apache.commons.net.ftp.FTPSClient._openDataConnection_(FTPSClient.java:622) at org.apache.commons.net.ftp.FTPClient._retrieveFile(FTPClient.java:1896) at org.apache.commons.net.ftp.FTPClient.retrieveFile(FTPClient.java:1882) at org.apache.camel.component.file.remote.FtpOperations.retrieveFileToFileInLocalWorkDirectory(FtpOperations.java:602) ... 10 common frames omitted 2021-06-17 01:40:09,577 [WARN ] (DefaultQuartzScheduler-camel-1_Worker-1) [org.apache.camel.component.file.remote.FtpConsumer.log]: Error processing file RemoteFile[Test3.xml] due to File operation failed: Read timed out. Code: 150. org.apache.camel.component.file.GenericFileOperationFailedException: File operation failed: Read timed out. Code: 150 at org.apache.camel.component.file.remote.FtpOperations.retrieveFileToFileInLocalWorkDirectory(FtpOperations.java:629) ... 2021-06-17 01:40:09,671 [WARN ] (DefaultQuartzScheduler-camel-1_Worker-1) [org.apache.camel.component.file.remote.FtpConsumer.log]: Error processing file RemoteFile[Test4.xml] due to Cannot retrieve file org.apache.camel.component.file.GenericFileOperationFailedException: Cannot retrieve file: RemoteFile[Test4.xml] from: ftps://example.com:1234... at org.apache.camel.component.file.GenericFileConsumer.processExchange(GenericFileConsumer.java:457) at org.apache.camel.component.file.remote.RemoteFileConsumer.processExchange(RemoteFileConsumer.java:147) at org.apache.camel.component.file.GenericFileConsumer.processBatch(GenericFileConsumer.java:240) at org.apache.camel.component.file.GenericFileConsumer.poll(GenericFileConsumer.java:201) at org.apache.camel.support.ScheduledPollConsumer.doRun(ScheduledPollConsumer.java:190) at org.apache.camel.support.ScheduledPollConsumer.run(ScheduledPollConsumer.java:107) at org.apache.camel.pollconsumer.quartz.QuartzScheduledPollConsumerJob.execute(QuartzScheduledPollConsumerJob.java:61) at org.quartz.core.JobRunShell.run(JobRunShell.java:202) at org.quartz.simpl.SimpleThreadPool$WorkerThread.run(SimpleThreadPool.java:573) 2021-06-17 01:40:12,718 [WARN ] (DefaultQuartzScheduler-camel-1_Worker-1) [org.apache.camel.component.file.remote.FtpConsumer.log]: Error processing file RemoteFile[Test5.xml] due to Cannot retrieve file org.apache.camel.component.file.GenericFileOperationFailedException: Cannot retrieve file: RemoteFile[Test5.xml] from: ftps://example.com:1234... ... 2021-06-17 01:40:12,718 [WARN ] (DefaultQuartzScheduler-camel-1_Worker-1) [org.apache.camel.component.file.remote.FtpConsumer.log]: Error processing file RemoteFile[Test6.xml] due to Cannot retrieve file org.apache.camel.component.file.GenericFileOperationFailedException: Cannot retrieve file: RemoteFile[Test6.xml] from: ftps://example.com:1234... ... 2021-06-17 01:40:12,734 [WARN ] (DefaultQuartzScheduler-camel-1_Worker-1) [org.apache.camel.component.file.remote.FtpConsumer.log]: Error processing file RemoteFile[Test7.xml] due to Cannot retrieve file org.apache.camel.component.file.GenericFileOperationFailedException: Cannot retrieve file: RemoteFile[Test7.xml] from: ftps://example.com:1234... ... 2021-06-17 01:45:12,749 [WARN ] (DefaultQuartzScheduler-camel-1_Worker-1) [org.apache.camel.component.file.remote.FtpConsumer.log]: Error processing file RemoteFile[Test8.xml] due to File operation failed: Read timed out. Code: 150. org.apache.camel.component.file.GenericFileOperationFailedException: File operation failed: Read timed out. Code: 150 at org.apache.camel.component.file.remote.FtpOperations.retrieveFileToFileInLocalWorkDirectory(FtpOperations.java:629) ... 2021-06-17 01:50:12,749 [WARN ] (DefaultQuartzScheduler-camel-1_Worker-1) [org.apache.camel.component.file.remote.FtpConsumer.log]: Error processing file RemoteFile[Test9.xml] due to File operation failed: Read timed out. Code: 150. org.apache.camel.component.file.GenericFileOperationFailedException: File operation failed: Read timed out. Code: 150 at org.apache.camel.component.file.remote.FtpOperations.retrieveFileToFileInLocalWorkDirectory(FtpOperations.java:629) ... 2021-06-17 01:50:12,827 [WARN ] (DefaultQuartzScheduler-camel-1_Worker-1) [org.apache.camel.component.file.remote.FtpConsumer.log]: Error processing file RemoteFile[Test10.xml] due to Cannot retrieve file org.apache.camel.component.file.GenericFileOperationFailedException: Cannot retrieve file: RemoteFile[Test10.xml] from: ftps://example.com:1234... at org.apache.camel.component.file.GenericFileConsumer.processExchange(GenericFileConsumer.java:457) ... 2021-06-17 01:50:22,030 [DEBUG] (DefaultQuartzScheduler-camel-1_Worker-1) [route.ftp-download]: Retrieving file from FTP: Test11.xml 2021-06-17 01:50:22,046 [INFO ] (DefaultQuartzScheduler-camel-1_Worker-1) [route.ftp-download]: Inbound file archived and sent to handling: Test11.xml 2021-06-17 01:50:22,187 [WARN ] (DefaultQuartzScheduler-camel-1_Worker-1) [org.apache.camel.component.file.remote.FtpConsumer.log]: Error processing file RemoteFile[Test12.xml] due to Cannot retrieve file org.apache.camel.component.file.GenericFileOperationFailedException: Cannot retrieve file: RemoteFile[Test12.xml] from: ftps://example.com:1234... at org.apache.camel.component.file.GenericFileConsumer.processExchange(GenericFileConsumer.java:457) ... 2021-06-17 01:50:22,359 [DEBUG] (DefaultQuartzScheduler-camel-1_Worker-1) [route.ftp-download]: Retrieving file from FTP: Test13.xml.xml 2021-06-17 01:50:22,359 [INFO ] (DefaultQuartzScheduler-camel-1_Worker-1) [route.ftp-download]: Inbound file archived and sent to handling: Test13.xml.xml 2021-06-17 01:50:22,531 [DEBUG] (DefaultQuartzScheduler-camel-1_Worker-1) [route.ftp-download]: Retrieving file from FTP: Test14.xml 2021-06-17 01:50:22,531 [INFO ] (DefaultQuartzScheduler-camel-1_Worker-1) [route.ftp-download]: Inbound file archived and sent to handling: Test14.xml Kind regards Carsten Bülow