pentaho/pentaho-kettle · error · KettleException

Mail.Log.ServerFieldEmpty

Error message

Mail.Log.ServerFieldEmpty

What it means

Thrown by Mail.validateMetaFields when meta.getServer() is empty, i.e. no SMTP server host was configured. Without an SMTP host the step cannot send mail at all, so it aborts during processRow before any rows are handled. This is a required-configuration check, not a connectivity error.

Solutions

  1. Set the SMTP server host in the Mail step dialog (e.g. smtp.yourdomain.com).
  2. Call meta.setServer("smtp.yourdomain.com") when building MailMeta in code.
  3. If you use a ${SMTP_SERVER} variable, confirm it is defined in kettle.properties or at launch, otherwise it resolves empty.

Example fix

// before
meta.setDestination("destField");
meta.setReplyAddress("reply@corp.com");
// after
meta.setDestination("destField");
meta.setReplyAddress("reply@corp.com");
meta.setServer("smtp.corp.com");
Defensive patterns

Strategy: validation

Validate before calling

if ( meta.getServer() == null || meta.getServer().trim().isEmpty() ) {
  throw new IllegalArgumentException("Mail step: SMTP server is required");
}

Try / catch

try { transformation.execute(); } catch ( KettleException e ) { if ( e.getMessage().contains("ServerFieldEmpty") ) { /* define ${SMTP_SERVER} or set meta.setServer(...) */ } else { throw e; } }

Prevention

When it happens

Trigger: Running the Mail step with the SMTP server field blank in the step dialog; MailMeta constructed in code without setServer(); server value referencing an environment-specific setting that was lost on import.

Common situations: Moving transformations between dev/prod where the SMTP host was hardcoded and removed; new users not realizing the server field is mandatory; KETTLE variable used for the server not defined so it resolves to empty.

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/d640ecac7f7d0b8e. Report an issue: GitHub.

Appendix: source

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

      processAttachedFiles();
    }
  }

  @VisibleForTesting
  void validateMetaFields( MailMeta meta ) throws KettleException {
    // Check is filename field is provided
    if ( Utils.isEmpty( meta.getDestination() ) ) {
      throw new KettleException( BaseMessages.getString( PKG, "Mail.Log.DestinationFieldEmpty" ) );
    }

    // Check is replyname field is provided
    if ( Utils.isEmpty( meta.getReplyAddress() ) ) {
      throw new KettleException( BaseMessages.getString( PKG, "Mail.Log.ReplyFieldEmpty" ) );
    }

    // Check is SMTP server is provided
    if ( Utils.isEmpty( meta.getServer() ) ) {
      throw new KettleException( BaseMessages.getString( PKG, "Mail.Log.ServerFieldEmpty" ) );
    }

    // Check Attached filenames when dynamic
    if ( meta.isDynamicFilename() && Utils.isEmpty( meta.getDynamicFieldname() ) ) {
      throw new KettleException( BaseMessages.getString( PKG, "Mail.Log.DynamicFilenameFieldEmpty" ) );
    }

    // Check Attached zipfilename when dynamic
    if ( meta.isZipFilenameDynamic() && Utils.isEmpty( meta.getDynamicZipFilenameField() ) ) {
      throw new KettleException( BaseMessages.getString( PKG, "Mail.Log.DynamicZipFilenameFieldEmpty" ) );
    }

    validateZipFiles( meta );

    // check authentication
    if ( meta.isUsingAuthentication().equals( AUTENTICATION_BASIC ) ) {
      // check authentication user
      if ( Utils.isEmpty( meta.getAuthenticationUser() ) ) {

View on GitHub (pinned to f3058517a1)