pentaho/pentaho-kettle · error · RuntimeException

sendMail: " + e.toString()

Error message

sendMail: " + e.toString()

What it means

Thrown by the sendMail() helper of the PDI Script step when Transport.send() or any mail-session setup fails. The original exception's toString() (e.g. javax.mail.MessagingException, UnknownHostException, AuthenticationFailedException) is appended, so the root cause is visible in the message.

Solutions

  1. Read the appended cause: fix the SMTP host/port per the wrapped exception (UnknownHostException -> hostname; Connection refused -> port/firewall; AuthenticationFailedException -> credentials).
  2. Verify network reachability from the Pentaho server: telnet/smtp connectivity to the mail host and port.
  3. Check that the SMTP server allows relay from this host, or add valid authentication if required.
  4. Prefer the dedicated Mail step or configure a central mail host in Kettle properties (KETTLE_SYSTEM_HOSTS / mail settings) instead of ad-hoc script sendMail.

Example fix

// before
sendMail('smtp.corp.local', 'etl@corp.com', 'ops@corp.com', 'Job done', 'OK')
// after (use a reachable, verified host)
sendMail('smtp.corp.com', 'etl@corp.com', 'ops@corp.com', 'Job done', 'OK')
Defensive patterns

Strategy: try-catch

Validate before calling

function canReachHost(host) {
  var s = new java.net.Socket();
  try { s.connect(new java.net.InetSocketAddress(host, 25), 3000); s.close(); return true; }
  catch (e) { return false; }
}
// call only if canReachMailHost before sendMail(...)

Try / catch

try { sendMail(host, from, to, subj, body); }
catch (e) {
  var cause = e.message.replace('sendMail: ', '');
  Logger.logError('SMTP failure: ' + cause);
  if (/UnknownHost/.test(cause)) { /* fix hostname */ }
  throw e;
}

Prevention

When it happens

Trigger: Calling sendMail(smtpServer, from, recipient, subject, body) where the SMTP host is unreachable/wrong, the port is blocked, authentication fails, or mail.jar/activation.jar connectivity issues occur.

Common situations: Firewall blocks outbound port 25, SMTP server hostname typo, no mail relay permission from the Pentaho server, TLS/SSL required by the server but not used, DNS failure inside containerized deployments.

Related errors


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

Appendix: source

Thrown at engine/src/main/java/org/pentaho/di/trans/steps/script/ScriptAddedFunctions.java:1245

        // Get Recipients
        String[] strArrRecipients = ( (String) ArgList[2] ).split( "," );

        InternetAddress[] addressTo = new InternetAddress[strArrRecipients.length];
        for ( int i = 0; i < strArrRecipients.length; i++ ) {
          addressTo[i] = new InternetAddress( strArrRecipients[i] );
        }
        msg.setRecipients( Message.RecipientType.TO, addressTo );

        // Optional : You can also set your custom headers in the Email if you Want
        msg.addHeader( "MyHeaderName", "myHeaderValue" );

        // Setting the Subject and Content Type
        msg.setSubject( (String) ArgList[3] );
        msg.setContent( ArgList[4], "text/plain" );
        Transport.send( msg );
      } catch ( Exception e ) {
        throw new RuntimeException( "sendMail: " + e.toString() );
      }
    } else {
      throw new RuntimeException( "The function call sendMail requires 5 arguments." );
    }
  }

  public static String upper( ScriptEngine actualContext, Bindings actualObject, Object[] ArgList,
    Object FunctionContext ) {
    String sRC = "";
    if ( ArgList.length == 1 ) {
      try {
        if ( isNull( ArgList[0] ) ) {
          return null;
        } else if ( isUndefined( ArgList[0] ) ) {
          return (String) undefinedValue;
        }
        sRC = (String) ArgList[0];
        sRC = sRC.toUpperCase();

View on GitHub (pinned to f3058517a1)