{"record":{"id":"2e413ae1dc4e0b7a","repo":"pentaho/pentaho-kettle","slug":"failed-to-list-directory","errorCode":null,"errorMessage":"Failed to list directory: ","messagePattern":"Failed to list directory: ","errorType":"exception","errorClass":"SftpException","httpStatus":null,"severity":"error","filePath":"engine/src/main/java/org/pentaho/di/core/ssh/mina/MinaSftpSession.java","lineNumber":51,"sourceCode":"    this.client = client;\n  }\n\n  @Override\n  public List<SftpFile> list( String path ) throws SftpException {\n    try {\n      List<SftpFile> out = new ArrayList<>();\n      for ( SftpClient.DirEntry e : client.readDir( path ) ) {\n        Attributes a = e.getAttributes();\n        Instant mtime = Instant.EPOCH;\n        if ( a.getModifyTime() != null ) {\n          // getModifyTime returns a FileTime; convert via toMillis()\n          mtime = Instant.ofEpochMilli( a.getModifyTime().toMillis() );\n        }\n        out.add( new SftpFile( e.getFilename(), a.isDirectory(), a.getSize(), mtime ) );\n      }\n      return out;\n    } catch ( IOException e ) {\n      throw new SftpException( \"Failed to list directory: \" + path, e );\n    }\n  }\n\n  @Override\n  public boolean exists( String path ) throws SftpException {\n    try {\n      client.stat( path );\n      return true;\n    } catch ( IOException e ) {\n      return false;\n    }\n  }\n\n  @Override\n  public boolean isDirectory( String path ) throws SftpException {\n    try {\n      return client.stat( path ).isDirectory();\n    } catch ( IOException e ) {","sourceCodeStart":33,"sourceCodeEnd":69,"githubUrl":"https://github.com/pentaho/pentaho-kettle/blob/f3058517a153da500bf4551f46d79b91bf8ec552/engine/src/main/java/org/pentaho/di/core/ssh/mina/MinaSftpSession.java#L33-L69","documentation":"MinaSftpSession.list() enumerates a remote SFTP directory via Apache MINA SSHD and wraps IOException in SftpException with 'Failed to list directory: <path>'. It indicates the remote directory listing could not be completed at the transport level.","triggerScenarios":"Calling list(path) when the remote path does not exist, the connection is broken/timed out mid-read, or the server denies directory read while opening fails with IOException.","commonSituations":"Wrong remote path/typo; SSH session dropped due to network issue or server timeout; permission denied on the remote directory; server closed connection.","solutions":["Verify the remote path exists and is a directory (call exists() first)","Check SFTP user permissions on the remote directory","Test connection stability/timeouts; reconnect the session before retrying","Inspect the wrapped IOException cause for the transport-level detail"],"exampleFix":"// before\nList<SftpFile> files = session.list(\"/data/reports\"); // path missing\n// after\nif (session.exists(\"/data/reports\")) {\n  List<SftpFile> files = session.list(\"/data/reports\");\n} else {\n  session.getMkdirs(\"/data/reports\");\n}","handlingStrategy":"try-catch","validationCode":"// Pre-check remote directory before listing\nif (!session.exists(remotePath)) throw new IllegalStateException(\"Remote path does not exist: \" + remotePath);\nif (!session.isDirectory(remotePath)) throw new IllegalStateException(\"Remote path is not a directory: \" + remotePath);","typeGuard":null,"tryCatchPattern":"try {\n  List<SftpFile> files = session.list(remotePath);\n} catch (SftpException e) {\n  if (e.getMessage().startsWith(\"Failed to list directory\")) {\n    log.error(\"SFTP listing failed for \" + remotePath, e.getCause());\n    reconnectAndRetry(remotePath);\n  } else throw e;\n}","preventionTips":["Call exists()/isDirectory before listing","Configure keep-alives and sane timeouts to avoid dropped SFTP sessions","Verify the SFTP account has read permission on target directories","Wrap listing in a bounded retry with reconnect on IOException"],"tags":["sftp","network","directory-listing"],"backgroundTag":"file-not-found","analyzedSha":"f3058517a153da500bf4551f46d79b91bf8ec552","analyzedAt":"2026-09-13T14:04:16.340Z","contentChangedAt":"2026-09-13T14:04:16.340Z","schemaVersion":2},"datasetVersion":"2026-09-20T23:17:15.980Z"}