{"record":{"id":"3545e492d81be505","repo":"pentaho/pentaho-kettle","slug":"jobentryftpdelete-socksproxy-portmissingexception","errorCode":"JobEntryFTPDelete.SocksProxy.PortMissingException","errorMessage":"JobEntryFTPDelete.SocksProxy.PortMissingException","messagePattern":"JobEntryFTPDelete\\.SocksProxy\\.PortMissingException","errorType":"exception","errorClass":"FTPException","httpStatus":null,"severity":"error","filePath":"plugins/ftp-delete/impl/src/main/java/org/pentaho/di/job/entries/ftpdelete/JobEntryFTPDelete.java","lineNumber":751,"sourceCode":"      result.setResult( true );\n      return result;\n    }\n\n    try {\n\n      // Get all the files in the current directory...\n      String[] filelist = null;\n      if ( copyprevious ) {\n        realFtpDirectory = \"\";\n      }\n      int timeoutValue = Const.toInt( environmentSubstitute( timeout ), 10000 );\n      if ( protocol.equals( PROTOCOL_FTP ) ) {\n        // If socks proxy server was provided\n        if ( !Utils.isEmpty( socksProxyHost ) ) {\n          if ( !Utils.isEmpty( socksProxyPort ) ) {\n            FTPClient.initSOCKS( environmentSubstitute( socksProxyPort ), environmentSubstitute( socksProxyHost ) );\n          } else {\n            throw new FTPException( BaseMessages.getString(\n              PKG, \"JobEntryFTPDelete.SocksProxy.PortMissingException\", environmentSubstitute( socksProxyHost ),\n              getName() ) );\n          }\n          // then if we have authentication information\n          if ( !Utils.isEmpty( socksProxyUsername ) && !Utils.isEmpty( socksProxyPassword ) ) {\n            FTPClient.initSOCKSAuthentication(\n              environmentSubstitute( socksProxyUsername ), Utils.resolvePassword( this, socksProxyPassword ) );\n          } else if ( !Utils.isEmpty( socksProxyUsername )\n            && Utils.isEmpty( socksProxyPassword ) || Utils.isEmpty( socksProxyUsername )\n            && !Utils.isEmpty( socksProxyPassword ) ) {\n            // we have a username without a password or vica versa\n            throw new FTPException( BaseMessages.getString(\n              PKG, \"JobEntryFTPDelete.SocksProxy.IncompleteCredentials\",\n              environmentSubstitute( socksProxyHost ), getName() ) );\n          }\n        }\n\n        if ( copyprevious ) {","sourceCodeStart":733,"sourceCodeEnd":769,"githubUrl":"https://github.com/pentaho/pentaho-kettle/blob/f3058517a153da500bf4551f46d79b91bf8ec552/plugins/ftp-delete/impl/src/main/java/org/pentaho/di/job/entries/ftpdelete/JobEntryFTPDelete.java#L733-L769","documentation":"During execute(), if the FTP protocol is used and a SOCKS proxy host is configured, a non-empty port is required to call FTPClient.initSOCKS. When socksProxyPort is empty the entry throws FTPException with the localized message key JobEntryFTPDelete.SocksProxy.PortMissingException, naming the substituted host and entry name.","triggerScenarios":"protocol==FTP, socksProxyHost non-empty, and socksProxyPort empty/null at execute time (variables in the port field resolve to empty).","commonSituations":"User filled in SOCKS host but left port blank; port stored as a ${VAR} whose variable is undefined; entry loaded from an older definition lacking the port attribute.","solutions":["Set the SOCKS proxy port in the job entry dialog","Define the variable used in the port field so environmentSubstitute yields a value","If no SOCKS proxy is needed, clear the SOCKS host field entirely","Validate host+port pairing in a pre-execution check"],"exampleFix":"// before\nsocksProxyHost = \"socks.corp.com\";\nsocksProxyPort = \"\"; // throws at execute\n// after\nsocksProxyHost = \"socks.corp.com\";\nsocksProxyPort = \"1080\";","handlingStrategy":"validation","validationCode":"String port = environmentSubstitute( socksProxyPort );\nif ( !Utils.isEmpty( socksProxyHost ) && Utils.isEmpty( port ) ) {\n  throw new FTPException( \"SOCKS proxy host is set but port is missing for entry \" + getName() );\n}","typeGuard":null,"tryCatchPattern":"try { jobEntry.execute( result, 0 ); }\ncatch ( FTPException fe ) {\n  if ( String.valueOf( fe.getMessage() ).contains( \"PortMissingException\" ) ) {\n    log.error( \"Set SOCKS port or clear SOCKS host in the job entry\" );\n  }\n}","preventionTips":["Always pair SOCKS host with a port in the entry dialog","Resolve ${VAR}s used for port before running jobs","Add a pre-execution config validation step"],"tags":["ftp","socks-proxy","configuration","job-entry"],"backgroundTag":"missing-required-config-field","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"}