pentaho/pentaho-kettle · error · KettleException

Mail.Exception.CouldnotFindPortField

Error message

Mail.Exception.CouldnotFindPortField

What it means

The Mail transformation step could not locate the port field in the incoming row's field metadata. The step is configured to read the SMTP port dynamically from a field, but data.previousRowMeta.indexOfValue(realPort) returned -1, meaning no field with that name exists in the input stream. Kettle throws this KettleException during cacheFieldsPosition before any mail is sent.

Solutions

  1. Open the Mail step settings and verify the 'Port' field name exactly matches a field in the input stream (names are case-sensitive).
  2. Check the upstream steps' field previews (right-click > Preview) to confirm the port field actually reaches this step.
  3. If the port is a fixed value instead, clear the Port field so the dynamic lookup is skipped.

Example fix

// before
String realPort = meta.getPort(); // "smtp_port" but row has "SMTP_PORT"
// after
// rename the field upstream or set the step's port field to "SMTP_PORT"
// or leave port field empty and hardcode the SMTP port in the settings
Defensive patterns

Strategy: validation

Validate before calling

// Before executing the transformation, verify the field exists:
if (meta.getPort() != null && !meta.getPort().isEmpty()) {
  if (rowMeta.indexOfValue(meta.getPort()) < 0) {
    throw new KettleException("Port field not found in input stream: " + meta.getPort());
  }
}

Try / catch

try { transformation.startThreads(); } catch (KettleException e) { if (e.getMessage().contains("CouldnotFindPortField")) { logError("Check the Mail step port field configuration"); } throw e; }

Prevention

When it happens

Trigger: meta.getPort() is non-empty (a port field name is configured) and the field name does not exactly match any field in the incoming row, so data.indexOfPort stays -1.

Common situations: Typo in the port field name in the Mail step dialog; an upstream step was renamed or removed so the field disappeared from the stream; case-sensitivity mismatch between configured name and actual field name.

Related errors


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

Appendix: source

Thrown at plugins/mail/impl/src/main/java/org/pentaho/di/trans/steps/mail/Mail.java:355

      }
    }
    // cache the position of the Server field
    if ( data.indexOfServer < 0 ) {
      String realServer = meta.getServer();
      data.indexOfServer = data.previousRowMeta.indexOfValue( realServer );
      if ( data.indexOfServer < 0 ) {
        throw new KettleException( BaseMessages.getString(
          PKG, "Mail.Exception.CouldnotFindServerField", realServer ) );
      }
    }
    // Port
    if ( !Utils.isEmpty( meta.getPort() ) ) {
      // cache the position of the port field
      if ( data.indexOfPort < 0 ) {
        String realPort = meta.getPort();
        data.indexOfPort = data.previousRowMeta.indexOfValue( realPort );
        if ( data.indexOfPort < 0 ) {
          throw new KettleException( BaseMessages.getString( PKG, "Mail.Exception.CouldnotFindPortField", realPort ) );
        }
      }
    }
    // Authentication
    if ( meta.isUsingAuthentication().equals( MailMeta.AUTENTICATION_BASIC ) ) {
      // cache the position of the Authentication password field
      if ( data.indexOfAuthenticationPass < 0 ) {
        String realAuthenticationPassword = Utils.resolvePassword( variables, meta.getAuthenticationPassword() );
        data.indexOfAuthenticationPass = data.previousRowMeta.indexOfValue( realAuthenticationPassword );
        if ( data.indexOfAuthenticationPass < 0 ) {
          throw new KettleException( BaseMessages.getString(
            PKG, "Mail.Exception.CouldnotFindAuthenticationPassField", realAuthenticationPassword ) );
        }
      }
    }
    // cache the position of the Authentication user field
    if ( meta.isUsingAuthentication().equals( MailMeta.AUTENTICATION_BASIC ) || meta.isUsingAuthentication().equals( MailMeta.AUTENTICATION_OAUTH ) ) {
      if ( data.indexOfAuthenticationUser < 0 ) {

View on GitHub (pinned to f3058517a1)