pentaho/pentaho-kettle · error · KettleException
Mail.Log.AuthenticationPasswordFieldEmpty
Error message
Mail.Log.AuthenticationPasswordFieldEmpty
What it means
Thrown by Mail.validateMetaFields when basic SMTP authentication is enabled but meta.getAuthenticationPassword() is empty. The username check (3195) has already passed, so the account name is set but its password is missing; the step aborts before attempting to send mail. This is metadata validation, not an SMTP authentication failure.
Solutions
- Enter the SMTP password (or the ${VARIABLE} containing it) in the Mail step's Authentication Password field.
- Call meta.setAuthenticationPassword("..." ) in code, ideally sourced from an environment variable rather than hardcoded.
- Confirm any referenced KETTLE variable is defined on the machine running the transformation.
- If no password is needed, switch authentication off rather than leaving basic auth enabled.
Example fix
// before
meta.setAuthenticationUser("smtpUser");
// after
meta.setAuthenticationUser("smtpUser");
meta.setAuthenticationPassword(System.getenv("SMTP_PASSWORD")); Defensive patterns
Strategy: validation
Validate before calling
if ( MailMeta.AUTENTICATION_BASIC.equals( meta.isUsingAuthentication() )
&& ( meta.getAuthenticationPassword() == null || meta.getAuthenticationPassword().trim().isEmpty() ) ) {
throw new IllegalArgumentException("Mail step: authentication password required for basic auth");
} Try / catch
try { transformation.execute(); } catch ( KettleException e ) { if ( e.getMessage().contains("AuthenticationPasswordFieldEmpty") ) { /* set password from secure env variable */ } else { throw e; } } Prevention
- Store SMTP passwords in kettle.properties or a vault, referenced by variable
- After credential rotation, re-deploy updated variables to all nodes
- Never export transformations with passwords stripped and assume they still work
When it happens
Trigger: Filling the Authentication User but leaving Authentication Password blank with basic auth enabled; password supplied via a ${variable} that is undefined so it resolves empty; code-built MailMeta setting the user but not setAuthenticationPassword(...).
Common situations: Security policies that strip passwords from exported transformations; passwords stored in kettle.properties not deployed to the executing node; users rotating credentials and clearing the password field.
Understand the failure class
- Authentication and authorization failures — expired tokens, bad credentials, and missing scopes.
Related errors
- Mail.Log.AuthenticationUserFieldEmpty
- Mail.Exception.CouldnotFindAuthenticationPassField
- Mail.Exception.CouldnotFindAuthenticationUserField
- Mail.Log.DestinationFieldEmpty
- Mail.Log.DynamicFilenameFieldEmpty
AI-assisted analysis of pentaho/pentaho-kettle@f3058517a1 (2026-09-13).
Data as JSON: /api/errors/bf9ab5744f630229.
Report an issue: GitHub.
Appendix: source
Thrown at plugins/mail/impl/src/main/java/org/pentaho/di/trans/steps/mail/Mail.java:497
}
// 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() ) ) {
throw new KettleException( BaseMessages.getString( PKG, "Mail.Log.AuthenticationUserFieldEmpty" ) );
}
// check authentication pass
if ( Utils.isEmpty( meta.getAuthenticationPassword() ) ) {
throw new KettleException( BaseMessages.getString( PKG, "Mail.Log.AuthenticationPasswordFieldEmpty" ) );
}
}
}
@VisibleForTesting
void validateZipFiles( MailMeta meta ) throws KettleException {
if ( meta.isZipFiles() && ( Utils.isEmpty( meta.getZipFilename() ) && !meta.isZipFilenameDynamic() ) ) {
throw new KettleException( BaseMessages.getString( PKG, "Mail.Log.ZipFilenameEmpty" ) );
}
}
@VisibleForTesting
void processAttachedFiles() throws KettleException {
if ( meta.isDynamicFilename() ) {
// cache the position of the attached source filename field
cacheSourceFileNameField();
// cache the position of the attached wildcard field
cacheWildCardField();View on GitHub (pinned to f3058517a1)