pentaho/pentaho-kettle · error · KettleException

Mail.Exception.CouldnotFindServerField

Error message

Mail.Exception.CouldnotFindServerField

What it means

Thrown by cacheFieldsPosition when the SMTP server field configured in Mail meta is not found in the incoming row's RowMeta. This lookup is unconditional: the step always expects the server field, so a missing column always aborts before any mail is sent.

Solutions

  1. Fix the 'SMTP Server fieldname' setting to an existing incoming column
  2. Add the server value upstream via Add constants if it is constant
  3. Re-select the field in the Mail step dialog after upstream layout changes

Example fix

// before
meta.setServer("smtp_host");
// after
meta.setServer("smtp_server"); // actual column in stream
Defensive patterns

Strategy: validation

Validate before calling

// the server lookup is unconditional: verify it always exists
if (rowMeta.indexOfValue(meta.getServer()) < 0) {
  logError("SMTP server field not in stream: " + meta.getServer());
}

Try / catch

try {
  step.processRow();
} catch (KettleException e) {
  if (e.getMessage().contains("CouldnotFindServerField")) {
    logError("SMTP server field missing: " + e.getMessage());
  }
}

Prevention

When it happens

Trigger: cacheFieldsPosition runs and data.indexOfServer == -1 after indexOfValue(meta.getServer()) on previousRowMeta.

Common situations: Server column dropped/renamed by an upstream step; configured a static SMTP host in the field-based setting; reusing step metadata against a differently shaped stream.

Understand the failure class

Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.

Related errors


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

Appendix: source

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

    }
    // Contact Phone
    if ( !Utils.isEmpty( meta.getContactPhone() ) ) {
      // cache the position of the destination field
      if ( data.indexOfContactPhone < 0 ) {
        String realContactPhone = meta.getContactPhone();
        data.indexOfContactPhone = data.previousRowMeta.indexOfValue( realContactPhone );
        if ( data.indexOfContactPhone < 0 ) {
          throw new KettleException( BaseMessages.getString(
            PKG, "Mail.Exception.CouldnotFindContactPhoneField", realContactPhone ) );
        }
      }
    }
    // 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 ) {

View on GitHub (pinned to f3058517a1)