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
- Read the appended cause: fix the SMTP host/port per the wrapped exception (UnknownHostException -> hostname; Connection refused -> port/firewall; AuthenticationFailedException -> credentials).
- Verify network reachability from the Pentaho server: telnet/smtp connectivity to the mail host and port.
- Check that the SMTP server allows relay from this host, or add valid authentication if required.
- 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
- Verify SMTP host/port reachability from the Pentaho server before go-live.
- Open firewall rules for the mail port in containerized/DMZ deployments.
- Confirm relay permissions or credentials on the mail server.
- Prefer the dedicated Mail job entry for production mail.
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
- sendMail
- JobGetMailsFromPOP.Error.Connecting
- JobGetMailsFromPOP.Error.NewConnection
- JobMail.Error.ReplyEmailNotFilled
- Mail.Error.ReplyEmailNotFilled
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)