{"record":{"id":"b755550674578e9e","repo":"apache/seatunnel","slug":"sftp-client-null-or-not-connected","errorCode":null,"errorMessage":"SFTP client null or not connected","messagePattern":"SFTP client null or not connected","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"seatunnel-connectors-v2/connector-file/connector-file-sftp/src/main/java/org/apache/seatunnel/connectors/seatunnel/file/sftp/system/SFTPInputStream.java","lineNumber":54,"sourceCode":"\n    private InputStream wrappedStream;\n    private ChannelSftp channel;\n    private SFTPConnectionPool connectionPool;\n    private FileSystem.Statistics stats;\n    private boolean closed;\n    private long pos;\n\n    SFTPInputStream(\n            InputStream stream,\n            ChannelSftp channel,\n            SFTPConnectionPool connectionPool,\n            FileSystem.Statistics stats) {\n\n        if (stream == null) {\n            throw new IllegalArgumentException(E_NULL_INPUT_STREAM);\n        }\n        if (channel == null || !channel.isConnected()) {\n            throw new IllegalArgumentException(E_CLIENT_NULL);\n        }\n        this.wrappedStream = stream;\n        this.channel = channel;\n        this.connectionPool = connectionPool;\n        this.stats = stats;\n\n        this.pos = 0;\n        this.closed = false;\n    }\n\n    @Override\n    public void seek(long position) throws IOException {\n        throw new IOException(E_SEEK_NOT_SUPPORTED);\n    }\n\n    @Override\n    public boolean seekToNewSource(long targetPos) throws IOException {\n        throw new IOException(E_SEEK_NOT_SUPPORTED);","sourceCodeStart":36,"sourceCodeEnd":72,"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/SFTPInputStream.java#L36-L72","documentation":"The SFTPInputStream constructor throws IllegalArgumentException when the ChannelSftp is null or not connected, since reads require a live SFTP channel. This fails fast at construction rather than producing confusing read errors later.","triggerScenarios":"Constructing SFTPInputStream (or calling its factory) with a channel that was never connected, or whose connection was dropped/closed by the pool or server before the stream is created.","commonSituations":"Reusing a pooled SFTP channel that the server already closed due to idle timeout; passing an unconnected ChannelSftp from custom code; connection pool exhausted/closed during job teardown.","solutions":["Obtain a connected channel from the SFTPConnectionPool (or connect it) before creating the stream.","Check channel.isConnected() before construction and reconnect if false.","Tune SFTP keep-alive/timeout settings to prevent idle disconnects in long jobs.","Verify connection pool configuration (max connections, idle eviction) is not closing channels prematurely."],"exampleFix":"// before\nSFTPInputStream s = new SFTPInputStream(in, staleChannel, pool, stats);\n// after\nif (channel == null || !channel.isConnected()) { channel = pool.connect(); }\nSFTPInputStream s = new SFTPInputStream(in, channel, pool, stats);","handlingStrategy":"type-guard","validationCode":"if (channel == null || !channel.isConnected()) { channel = pool.connect(); }","typeGuard":"boolean usable(ChannelSftp c) { return c != null && c.isConnected(); }","tryCatchPattern":"try { in = SFTPInputStream.getInstance(path, ...); }\ncatch (IllegalArgumentException e) { channel = pool.connect(); in = SFTPInputStream.getInstance(path, ...); }","preventionTips":["Always fetch channels from the connection pool, never share raw channels across threads","Tune keep-alive/timeout so channels survive long jobs","Check isConnected() before any SFTP operation"],"tags":["sftp","inputstream","connection","illegalargument"],"backgroundTag":"connection-refused","analyzedSha":"cf67b549a7a6c35fa0beb12d83c62892427ea919","analyzedAt":"2026-09-10T21:44:55.265Z","contentChangedAt":"2026-09-10T21:44:55.265Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}