pentaho/pentaho-kettle · error · KettleException
Mail.Log.ZipFilenameEmpty
Error message
Mail.Log.ZipFilenameEmpty
What it means
Thrown by Mail.validateZipFiles (invoked from validateMetaFields) when the step is configured to zip attachments (meta.isZipFiles() is true), the zip filename is not dynamic, and meta.getZipFilename() is empty. With zipping enabled and no dynamic field, a static zip file name is mandatory, so the step aborts during processRow.
Solutions
- Set the static Zip Filename in the Mail step dialog (e.g. /tmp/attachments.zip).
- Call meta.setZipFilename("/tmp/attachments.zip") in code, or enable dynamic mode and set the dynamic zip field instead.
- If zipping is unnecessary, disable the zip-files option.
Example fix
// before
meta.setZipFiles(true);
// after
meta.setZipFiles(true);
meta.setZipFilename("/tmp/attachments.zip"); Defensive patterns
Strategy: validation
Validate before calling
if ( meta.isZipFiles() && !meta.isZipFilenameDynamic()
&& ( meta.getZipFilename() == null || meta.getZipFilename().trim().isEmpty() ) ) {
throw new IllegalArgumentException("Mail step: zip filename required when zipping without dynamic field");
} Try / catch
try { transformation.execute(); } catch ( KettleException e ) { if ( e.getMessage().contains("ZipFilenameEmpty") ) { /* set zipFilename or enable dynamic zip */ } else { throw e; } } Prevention
- Whenever enabling zip, set either a static filename or a dynamic field
- Review zip-related settings together as a unit
- Test mail-with-attachments transformations in staging before production
When it happens
Trigger: Enabling 'zip attachments' in the Mail step with the Zip Filename field left blank and the dynamic zip option off; code-built MailMeta with setZipFiles(true) but neither setZipFilename(...) nor dynamic mode.
Common situations: Toggling zip on and forgetting the filename; the static zip name removed during a config cleanup while dynamic mode was not enabled; transformations copied between projects losing the zip filename value.
Understand the failure class
Background: "must not be empty", "cannot be empty" — required-field validation errors across open-source libraries — this error's family across 41 libraries.
Related errors
- Mail.Log.DynamicZipFilenameFieldEmpty
- Mail.Log.AuthenticationPasswordFieldEmpty
- Mail.Log.AuthenticationUserFieldEmpty
- Mail.Log.DestinationFieldEmpty
- Mail.Log.DynamicFilenameFieldEmpty
AI-assisted analysis of pentaho/pentaho-kettle@f3058517a1 (2026-09-13).
Data as JSON: /api/errors/30f58ab0a48c934a.
Report an issue: GitHub.
Appendix: source
Thrown at plugins/mail/impl/src/main/java/org/pentaho/di/trans/steps/mail/Mail.java:505
// 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();
} else {
// static attached filenames
data.realSourceFileFoldername = environmentSubstitute( meta.getSourceFileFoldername() );
data.realSourceWildcard = environmentSubstitute( meta.getSourceWildcard() );
}
}
private void cacheWildCardField() throws KettleException {View on GitHub (pinned to f3058517a1)