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
- Open the Mail step settings and verify the 'Port' field name exactly matches a field in the input stream (names are case-sensitive).
- Check the upstream steps' field previews (right-click > Preview) to confirm the port field actually reaches this step.
- 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
- Always preview the input rows of the Mail step after changing upstream steps.
- Use the field-name dropdowns in the step dialog instead of typing names manually.
- Re-check field names after any upstream rename or refactor.
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
- Mail.Exception.CouldnotFindCommentField
- Mail.Exception.CouldnotFindSubjectField
- File name field [ ] couldn't be found in the input stream!
- Mail.Exception.AttachedContentFieldEmpty
- Mail.Exception.AttachedContentFileNameFieldEmpty
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)