{"record":{"id":"e5dae1f961b7913d","repo":"pentaho/pentaho-kettle","slug":"jobftpput-socksproxy-portmissingexception","errorCode":"JobFTPPUT.SocksProxy.PortMissingException","errorMessage":"JobFTPPUT.SocksProxy.PortMissingException","messagePattern":"JobFTPPUT\\.SocksProxy\\.PortMissingException","errorType":"error_code","errorClass":"FTPException","httpStatus":null,"severity":"error","filePath":"plugins/put-a-file-with-ftp/impl/src/main/java/org/pentaho/di/job/entries/ftpput/JobEntryFTPPUT.java","lineNumber":837,"sourceCode":"    int timeoutValue = Const.toInt( environmentSubstitute( timeout ), 10000 );\n    ftpClient.setTimeout( timeoutValue );\n    if ( log.isDetailed() ) {\n      logDetailed( BaseMessages.getString( PKG, \"JobFTPPUT.Log.SetTimeout\", String.valueOf( timeoutValue ) ) );\n    }\n\n\n    ftpClient.setControlEncoding( controlEncoding );\n    if ( log.isDetailed() ) {\n      logDetailed( BaseMessages.getString( PKG, \"JobFTPPUT.Log.SetEncoding\", controlEncoding ) );\n    }\n\n    // If socks proxy server was provided\n    if ( !Utils.isEmpty( socksProxyHost ) ) {\n      // if a port was provided\n      if ( !Utils.isEmpty( socksProxyPort ) ) {\n        FTPClient.initSOCKS( environmentSubstitute( socksProxyPort ), environmentSubstitute( socksProxyHost ) );\n      } else { // looks like we have a host and no port\n        throw new FTPException( BaseMessages.getString(\n          PKG, \"JobFTPPUT.SocksProxy.PortMissingException\", environmentSubstitute( socksProxyHost ) ) );\n      }\n      // now if we have authentication information\n      if ( !Utils.isEmpty( socksProxyUsername )\n        && Utils.isEmpty( socksProxyPassword ) || Utils.isEmpty( socksProxyUsername )\n        && !Utils.isEmpty( socksProxyPassword ) ) {\n        // we have a username without a password or vice versa\n        throw new FTPException( BaseMessages.getString(\n          PKG, \"JobFTPPUT.SocksProxy.IncompleteCredentials\", environmentSubstitute( socksProxyHost ),\n          getName() ) );\n      }\n    }\n\n    return ftpClient;\n  }\n\n  // package-local visibility for testing purposes\n  FTPClient createFtpClient() {","sourceCodeStart":819,"sourceCodeEnd":855,"githubUrl":"https://github.com/pentaho/pentaho-kettle/blob/f3058517a153da500bf4551f46d79b91bf8ec552/plugins/put-a-file-with-ftp/impl/src/main/java/org/pentaho/di/job/entries/ftpput/JobEntryFTPPUT.java#L819-L855","documentation":"When building the FTP client, the entry throws FTPException 'SocksProxy.PortMissingException' (message key JobFTPPUT.SocksProxy.PortMissingException, host interpolated into the message) when a SOCKS proxy host is configured but the SOCKS proxy port is empty. FTPClient.initSOCKS requires both host and port.","triggerScenarios":"Executing the FTP Put entry with Socks proxy host set (non-empty socksProxyHost) but socksProxyPort left blank.","commonSituations":"Copy-pasting a proxy config and forgetting the port; environment variable for the port not defined; port field cleared during edit.","solutions":["Enter the SOCKS proxy port in the job entry's Socks proxy settings (e.g. 1080).","If the port is a variable, ensure it resolves to a non-empty value at runtime.","Clear the SOCKS proxy host entirely if you don't intend to use a SOCKS proxy (host and port are both-or-neither).","Validate host/port pair in job metadata before deployment."],"exampleFix":"// before\nsocksProxyHost = \"proxy.corp.com\";\nsocksProxyPort = \"\"; // empty -> exception\n\n// after\nsocksProxyHost = \"proxy.corp.com\";\nsocksProxyPort = \"1080\";","handlingStrategy":"validation","validationCode":"if ( !Utils.isEmpty(entry.getSocksProxyHost()) && Utils.isEmpty(entry.getSocksProxyPort()) ) { throw new IllegalArgumentException(\"SOCKS proxy host set but port missing\"); }","typeGuard":null,"tryCatchPattern":"try { result = runFtpPut(); } catch (FTPException e) { if ( e.getMessage().contains(\"PortMissingException\") || e.getMessage().contains(\"SOCKS\") ) { failJob(\"Configure both SOCKS proxy host and port\"); } else { throw e; } }","preventionTips":["Treat SOCKS host and port as an all-or-nothing pair when configuring entries.","Verify proxy variables resolve before scheduling the job.","Standardize proxy settings via shared environment configuration."],"tags":["ftp","socks-proxy","configuration","missing-port"],"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"}