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

  1. Provide both the SOCKS proxy username and password in the job entry
  2. If the password uses ${VAR} variable syntax, confirm the environment variable/parameter is set at runtime
  3. 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

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


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)