{"record":{"id":"1b643a73afec9ebc","repo":"pentaho/pentaho-kettle","slug":"jobentryftp-socksproxy-incompletecredentials","errorCode":null,"errorMessage":"JobEntryFTP.SocksProxy.IncompleteCredentials","messagePattern":"JobEntryFTP\\.SocksProxy\\.IncompleteCredentials","errorType":"exception","errorClass":"FTPException","httpStatus":null,"severity":"error","filePath":"plugins/get-file-with-ftp/impl/src/main/java/org/pentaho/di/job/entries/ftp/JobEntryFTP.java","lineNumber":989,"sourceCode":"\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, \"JobEntryFTP.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, \"JobEntryFTP.SocksProxy.IncompleteCredentials\", environmentSubstitute( socksProxyHost ),\n            getName() ) );\n        }\n      }\n\n      // login to ftp host ...\n      ftpclient.connect();\n\n      String realUsername =\n        environmentSubstitute( userName )\n          + ( !Utils.isEmpty( proxyHost ) ? \"@\" + realServername : \"\" )\n          + ( !Utils.isEmpty( proxyUsername ) ? \" \" + environmentSubstitute( proxyUsername ) : \"\" );\n\n      String realPassword =\n        Utils.resolvePassword( this, password )\n          + ( !Utils.isEmpty( proxyPassword ) ? \" \"\n          + Utils.resolvePassword( this, proxyPassword ) : \"\" );\n","sourceCodeStart":971,"sourceCodeEnd":1007,"githubUrl":"https://github.com/pentaho/pentaho-kettle/blob/f3058517a153da500bf4551f46d79b91bf8ec552/plugins/get-file-with-ftp/impl/src/main/java/org/pentaho/di/job/entries/ftp/JobEntryFTP.java#L971-L1007","documentation":"When a SOCKS proxy is configured for the FTP job entry, both a username and a password must be supplied for authentication. If exactly one of them is set (username without password or vice versa), the entry throws an FTPException with this localized message, since partial credentials cannot be used with initSOCKSAuthentication.","triggerScenarios":"Executing the job entry with socksProxyUsername set but socksProxyPassword empty, or socksProxyPassword set but socksProxyUsername empty, while socksProxyHost is configured.","commonSituations":"Storing the proxy password in an environment variable that is unset at runtime (resolvePassword/env substitution yields empty); half-completed proxy credentials after a config migration; someone clearing the password field for security.","solutions":["Provide both the SOCKS proxy username and password in the job entry","If the password uses ${VAR} variable syntax, confirm the environment variable/parameter is set at runtime","If the proxy needs no auth, clear BOTH username and password fields"],"exampleFix":"// before\nSOCKS proxy username: proxyUser\nSOCKS proxy password: (empty)\n// after\nSOCKS proxy username: proxyUser\nSOCKS proxy password: ${PROXY_PASS}   // with PROXY_PASS exported at runtime","handlingStrategy":"validation","validationCode":"if (!Utils.isEmpty(socksProxyHost)) { boolean hasUser = !Utils.isEmpty(socksProxyUsername); boolean hasPass = !Utils.isEmpty(socksProxyPassword); if (hasUser != hasPass) { throw new IllegalArgumentException(\"SOCKS proxy requires both username and password, or neither\"); } }","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Set both credentials fields together, or clear both","Ensure password environment variables/parameters are defined at runtime","Avoid clearing just the password field when editing configs","Test with a dry run before production execution"],"tags":["ftp","socks-proxy","credentials"],"backgroundTag":"missing-credentials","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"}