pentaho/pentaho-kettle · error · FTPException
JobEntryFTP.SocksProxy.IncompleteCredentials
Error message
JobEntryFTP.SocksProxy.IncompleteCredentials
What it means
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.
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
Example fix
// before
SOCKS proxy username: proxyUser
SOCKS proxy password: (empty)
// after
SOCKS proxy username: proxyUser
SOCKS proxy password: ${PROXY_PASS} // with PROXY_PASS exported at runtime Defensive patterns
Strategy: validation
Validate before calling
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"); } } Prevention
- 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
When it happens
Trigger: Executing the job entry with socksProxyUsername set but socksProxyPassword empty, or socksProxyPassword set but socksProxyUsername empty, while socksProxyHost is configured.
Common situations: 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.
Related errors
- JobFTPPUT.SocksProxy.IncompleteCredentials
- JobEntryFTP.SocksProxy.PortMissingException
- JobEntryFTPDelete.SocksProxy.IncompleteCredentials
- JobEntryFTPDelete.SocksProxy.PortMissingException
- JobFTPPUT.SocksProxy.PortMissingException
AI-assisted analysis of pentaho/pentaho-kettle@f3058517a1 (2026-09-13).
Data as JSON: /api/errors/1b643a73afec9ebc.
Report an issue: GitHub.
Appendix: source
Thrown at plugins/get-file-with-ftp/impl/src/main/java/org/pentaho/di/job/entries/ftp/JobEntryFTP.java:989
// If socks proxy server was provided
if ( !Utils.isEmpty( socksProxyHost ) ) {
if ( !Utils.isEmpty( socksProxyPort ) ) {
FTPClient.initSOCKS( environmentSubstitute( socksProxyPort ), environmentSubstitute( socksProxyHost ) );
} else {
throw new FTPException( BaseMessages.getString(
PKG, "JobEntryFTP.SocksProxy.PortMissingException", environmentSubstitute( socksProxyHost ),
getName() ) );
}
// then if we have authentication information
if ( !Utils.isEmpty( socksProxyUsername ) && !Utils.isEmpty( socksProxyPassword ) ) {
FTPClient.initSOCKSAuthentication(
environmentSubstitute( socksProxyUsername ), Utils.resolvePassword( this, socksProxyPassword ) );
} else if ( !Utils.isEmpty( socksProxyUsername )
&& Utils.isEmpty( socksProxyPassword ) || Utils.isEmpty( socksProxyUsername )
&& !Utils.isEmpty( socksProxyPassword ) ) {
// we have a username without a password or vica versa
throw new FTPException( BaseMessages.getString(
PKG, "JobEntryFTP.SocksProxy.IncompleteCredentials", environmentSubstitute( socksProxyHost ),
getName() ) );
}
}
// login to ftp host ...
ftpclient.connect();
String realUsername =
environmentSubstitute( userName )
+ ( !Utils.isEmpty( proxyHost ) ? "@" + realServername : "" )
+ ( !Utils.isEmpty( proxyUsername ) ? " " + environmentSubstitute( proxyUsername ) : "" );
String realPassword =
Utils.resolvePassword( this, password )
+ ( !Utils.isEmpty( proxyPassword ) ? " "
+ Utils.resolvePassword( this, proxyPassword ) : "" );
View on GitHub (pinned to f3058517a1)