{"record":{"id":"0f82750922cb475a","repo":"apache/seatunnel","slug":"sftpexception-wrapped-pwd-failed-while-deleting","errorCode":null,"errorMessage":"SftpException wrapped (pwd failed while deleting)","messagePattern":"SftpException wrapped \\(pwd failed while deleting\\)","errorType":"exception","errorClass":"IOException","httpStatus":null,"severity":"error","filePath":"seatunnel-connectors-v2/connector-file/connector-file-sftp/src/main/java/org/apache/seatunnel/connectors/seatunnel/file/sftp/system/SFTPFileSystem.java","lineNumber":359,"sourceCode":"            return !getFileStatus(channel, file).isDirectory();\n        } catch (FileNotFoundException e) {\n            return false; // file does not exist\n        } catch (IOException ioe) {\n            throw new IOException(E_FILE_CHECK_FAILED, ioe);\n        }\n    }\n\n    /**\n     * Convenience method, so that we don't open a new connection when using this method from within\n     * another method. Otherwise every API invocation incurs the overhead of opening/closing a TCP\n     * connection.\n     */\n    private boolean delete(ChannelSftp channel, Path file, boolean recursive) throws IOException {\n        Path workDir;\n        try {\n            workDir = new Path(channel.pwd());\n        } catch (SftpException e) {\n            throw new IOException(e);\n        }\n        Path absolute = makeAbsolute(workDir, file);\n        String pathName = absolute.toUri().getPath();\n        FileStatus fileStat = null;\n        try {\n            fileStat = getFileStatus(channel, absolute);\n        } catch (FileNotFoundException e) {\n            // file not found, no need to delete, return true\n            return false;\n        }\n        if (!fileStat.isDirectory()) {\n            boolean status = true;\n            try {\n                channel.rm(pathName);\n            } catch (SftpException e) {\n                status = false;\n            }\n            return status;","sourceCodeStart":341,"sourceCodeEnd":377,"githubUrl":"https://github.com/apache/seatunnel/blob/cf67b549a7a6c35fa0beb12d83c62892427ea919/seatunnel-connectors-v2/connector-file/connector-file-sftp/src/main/java/org/apache/seatunnel/connectors/seatunnel/file/sftp/system/SFTPFileSystem.java#L341-L377","documentation":"SFTPFileSystem.delete() first resolves the current remote working directory via channel.pwd(); if the SFTP server rejects that call the SftpException is wrapped in an IOException with no added context. It means the 'pwd' step failed while attempting a delete, typically because the underlying SSH/SFTP channel is dead, not authenticated, or the server errored.","triggerScenarios":"Calling delete(path), delete(path, recursive) or a create() that deletes an existing file for overwrite, when channel.pwd() throws (session closed by server, connection dropped, auth expired, or server-side failure on the pwd request).","commonSituations":"SFTP session idle timeout between connect and delete; network interruption mid-job; server closes channel after MAX_SESSIONS limit; using a channel returned to the pool after failure; firewall dropping long-lived SSH connections.","solutions":["Check SFTP server connectivity and that the session/channel is still authenticated before the delete","Reconnect (connect() / return channel to pool and re-acquire) and retry the delete","Increase SSH keep-alive / ServerAliveInterval settings on the client to prevent idle disconnects","Inspect the wrapped SftpException's id (e.g. SSH_FX_FAILURE vs SSH_FX_CONNECTION_LOST) to distinguish server error from dropped connection"],"exampleFix":"// before\nboolean ok = fs.delete(new Path(\"/tmp/data/file.txt\"), false);\n// after\ntry {\n    boolean ok = fs.delete(new Path(\"/tmp/data/file.txt\"), false);\n} catch (IOException e) {\n    if (e.getCause() instanceof SftpException) {\n        // reconnect / retry delete\n    }\n    throw e;\n}","handlingStrategy":"try-catch","validationCode":"boolean healthy = false;\ntry {\n    fs.getFileStatus(new Path(\".\"));\n    healthy = true;\n} catch (IOException e) {\n    healthy = false;\n}","typeGuard":null,"tryCatchPattern":"try {\n    fs.delete(path, recursive);\n} catch (IOException e) {\n    if (e.getCause() instanceof SftpException) { /* reconnect + retry */ }\n    throw e;\n}","preventionTips":["Enable SSH keep-alive to avoid idle session drops","Revalidate pooled channels before reuse","Retry transient connection failures with backoff","Monitor SFTP server session limits"],"tags":["sftp","io","connection"],"backgroundTag":"connection-refused","analyzedSha":"cf67b549a7a6c35fa0beb12d83c62892427ea919","analyzedAt":"2026-09-10T21:44:55.265Z","contentChangedAt":"2026-09-10T21:44:55.265Z","schemaVersion":2},"datasetVersion":"2026-09-14T11:17:12.474Z"}