pentaho/pentaho-kettle · error · FTPException

JobEntryFTPDelete.SocksProxy.IncompleteCredentials

JobEntryFTPDelete.SocksProxy.IncompleteCredentials

Error message

JobEntryFTPDelete.SocksProxy.IncompleteCredentials

What it means

If a SOCKS proxy host is configured for the FTP protocol, SOCKS authentication requires both username and password. When exactly one of the two is provided, execute() throws FTPException with key JobEntryFTPDelete.SocksProxy.IncompleteCredentials, naming the host and job entry name.

Solutions

  1. Provide both SOCKS username and password (or leave both empty for no auth)
  2. Ensure the password variable resolves to a non-empty value at runtime
  3. Clear both fields if the proxy needs no authentication
  4. Use Utils.resolvePassword-compatible encrypted storage so the password persists

Example fix

// before
socksProxyUsername = "ftpuser";
socksProxyPassword = ""; // incomplete credentials
// after
socksProxyUsername = "ftpuser";
socksProxyPassword = Encr.encryptPasswordIfNotUsingVariables( "secret" );
Defensive patterns

Strategy: validation

Validate before calling

boolean hasUser = !Utils.isEmpty( socksProxyUsername );
boolean hasPass = !Utils.isEmpty( Utils.resolvePassword( this, socksProxyPassword ) );
if ( !Utils.isEmpty( socksProxyHost ) && hasUser != hasPass ) {
  throw new FTPException( "SOCKS proxy credentials incomplete for entry " + getName() );
}

Try / catch

try { jobEntry.execute( result, 0 ); }
catch ( FTPException fe ) {
  if ( String.valueOf( fe.getMessage() ).contains( "IncompleteCredentials" ) ) {
    log.error( "Provide both SOCKS username and password, or neither" );
  }
}

Prevention

When it happens

Trigger: protocol==FTP, socksProxyHost set, and XOR condition holds: username non-empty with empty password, or password non-empty with empty username.

Common situations: User entered SOCKS username but left password blank (or vice versa); password stored as ${VAR} that resolves to empty; entry partially migrated from XML/repository where one field was lost.

Related errors


AI-assisted analysis of pentaho/pentaho-kettle@f3058517a1 (2026-09-13). Data as JSON: /api/errors/1ef1531e6eee73f2. Report an issue: GitHub.

Appendix: source

Thrown at plugins/ftp-delete/impl/src/main/java/org/pentaho/di/job/entries/ftpdelete/JobEntryFTPDelete.java:763

      if ( protocol.equals( PROTOCOL_FTP ) ) {
        // 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, "JobEntryFTPDelete.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, "JobEntryFTPDelete.SocksProxy.IncompleteCredentials",
              environmentSubstitute( socksProxyHost ), getName() ) );
          }
        }

        if ( copyprevious ) {
          realFtpDirectory = "";
        }

        // establish the connection
        FTPConnect(
          realservername, realUsername, realPassword, realserverport, realFtpDirectory, realproxyhost,
          realproxyusername, realproxypassword, realproxyport, timeoutValue );

        filelist = ftpclient.dir();
      } else if ( protocol.equals( PROTOCOL_FTPS ) ) {
        // establish the secure connection
        FTPSConnect( realservername, realUsername, realserverport, realPassword, realFtpDirectory, timeoutValue );

View on GitHub (pinned to f3058517a1)