pentaho/pentaho-kettle · error · FTPException

JobFTPPUT.SocksProxy.PortMissingException

JobFTPPUT.SocksProxy.PortMissingException

Error message

JobFTPPUT.SocksProxy.PortMissingException

What it means

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.

Solutions

  1. Enter the SOCKS proxy port in the job entry's Socks proxy settings (e.g. 1080).
  2. If the port is a variable, ensure it resolves to a non-empty value at runtime.
  3. Clear the SOCKS proxy host entirely if you don't intend to use a SOCKS proxy (host and port are both-or-neither).
  4. Validate host/port pair in job metadata before deployment.

Example fix

// before
socksProxyHost = "proxy.corp.com";
socksProxyPort = ""; // empty -> exception

// after
socksProxyHost = "proxy.corp.com";
socksProxyPort = "1080";
Defensive patterns

Strategy: validation

Validate before calling

if ( !Utils.isEmpty(entry.getSocksProxyHost()) && Utils.isEmpty(entry.getSocksProxyPort()) ) { throw new IllegalArgumentException("SOCKS proxy host set but port missing"); }

Try / catch

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; } }

Prevention

When it happens

Trigger: Executing the FTP Put entry with Socks proxy host set (non-empty socksProxyHost) but socksProxyPort left blank.

Common situations: Copy-pasting a proxy config and forgetting the port; environment variable for the port not defined; port field cleared during edit.

Understand the failure class

Background: "is required", "must be set", "missing required field": configuration validation errors across open-source libraries — this error's family across 36 libraries.

Related errors


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

Appendix: source

Thrown at plugins/put-a-file-with-ftp/impl/src/main/java/org/pentaho/di/job/entries/ftpput/JobEntryFTPPUT.java:837

    int timeoutValue = Const.toInt( environmentSubstitute( timeout ), 10000 );
    ftpClient.setTimeout( timeoutValue );
    if ( log.isDetailed() ) {
      logDetailed( BaseMessages.getString( PKG, "JobFTPPUT.Log.SetTimeout", String.valueOf( timeoutValue ) ) );
    }


    ftpClient.setControlEncoding( controlEncoding );
    if ( log.isDetailed() ) {
      logDetailed( BaseMessages.getString( PKG, "JobFTPPUT.Log.SetEncoding", controlEncoding ) );
    }

    // If socks proxy server was provided
    if ( !Utils.isEmpty( socksProxyHost ) ) {
      // if a port was provided
      if ( !Utils.isEmpty( socksProxyPort ) ) {
        FTPClient.initSOCKS( environmentSubstitute( socksProxyPort ), environmentSubstitute( socksProxyHost ) );
      } else { // looks like we have a host and no port
        throw new FTPException( BaseMessages.getString(
          PKG, "JobFTPPUT.SocksProxy.PortMissingException", environmentSubstitute( socksProxyHost ) ) );
      }
      // now if we have authentication information
      if ( !Utils.isEmpty( socksProxyUsername )
        && Utils.isEmpty( socksProxyPassword ) || Utils.isEmpty( socksProxyUsername )
        && !Utils.isEmpty( socksProxyPassword ) ) {
        // we have a username without a password or vice versa
        throw new FTPException( BaseMessages.getString(
          PKG, "JobFTPPUT.SocksProxy.IncompleteCredentials", environmentSubstitute( socksProxyHost ),
          getName() ) );
      }
    }

    return ftpClient;
  }

  // package-local visibility for testing purposes
  FTPClient createFtpClient() {

View on GitHub (pinned to f3058517a1)